Note on Units of measurement

We know from simple regression that change the units of measurement of the dependent variable or some of the independent variables cannot change the interpretation of the OLS regression line.

This means that if we rescale any of our variables, the coefficients have to change to keep the interpretation unchanged.

  1. If we multiply the dependent variable y by a nonzero constant, say c, all of the coefficients – the intercept and the slopes – get multiplied by c. So do the fitted values and residuals. Nothing happens to the R-squared. Nothing happens to t statistics (except they change sign if c < 0) or F statistics.

  2. If we multiply an independent variable \(x_j\) by the nonzero constant c then the coefficient in \(x_j\) gets divided by c. Nothing happens to fitted values, residuals, or R-squared. Nothing happens to t or F statistics, except the t statistic on the new \(x_j\) variable changes sign if c < 0.

  3. Suppose y > 0 and we initially use log(y) as the dependent variable. If we first multiply y by the constant c > 0 and then take the log, only the intercept in the regression will change. This is because log(c · y) = log(c) + log(y). As an example, suppose y is initially in thousands of dollars. Then 1, 000 · y is in dollars. Now log(1, 000 · y) = log(1, 000) + log(y) ≈ 6.91, and so the intercept will increase by about 6.91. None of the slopes changes. The fitted values each increases by 6.91, but the residuals and R-squared do not change. Nothing happens to t or F statistics.

  4. If we use \(log(c · x_j)\) instead of \(log(x_j)\), the intercept changes but the coefficient on \(x_j\) does not; neither does the R-squared or any test statistics (except for those relating to the intercept).

Using a Natural Log

Reasons for Using the Natural Log

  1. The coefficients have percentage change interpretations. Consequently, we can be ignorant of the units of measurement of any variable that appears in logarithmic form.

  2. When y > 0, models with log(y) as the dependent variable often more closely satisfy the classical linear model assumptions. For example, the model has a better chance of being linear, homoskedasticity is more likely to hold, and normality is often much more plausible. (These are observations based on experience.)

  3. In most cases, taking the log greatly reduces the variance of a variable, making OLS estimates less prone to outlier influence.

Limitations of Using the Natural Log

  1. If y ≥ 0 but y = 0 is possible, we cannot use log(y). Sometimes log(1 + y) is used, but interpretation of the coefficients is difficult, and log(1 + y) ≥ 0 if y ≥ 0.

  2. It is harder to predict y when we have estimated a model for log(y).

  3. In cases where y is a fraction and close to zero for many observations, log(\(y_i\)) can have more variability than \(y_i\).

Consider unem, the unemployment rate. Because unemployment is a percent, changes are percentage point changes. So, unem going from 8 to 9 is a one percentage point increase, but it is a 12.5 percent increase from the starting value of 8. The logarithmic change is log(9) − log(8) ≈ .118, which means approximately 11.8% as the approximation to 12.5%. Usually we are more interested in the effect of a one percentage point change, but not always.

Some (Not-so-Hard) Rules on Using Logarithms

  1. Logs are often used for dollar amounts that are always positive, as well as for variables such as population, especially when there is a lot of variation.

  2. Logs are used less often for variables measured in years, such as schooling, age, and experience. We often want to know what the effect of increasing schooling by one year (not by a certain percentage).

  3. Logs are used less infrequently for variables that are already percents or proportions.

log-lin

We can approximate percentage changes using the natural log

Now let the dependent variable be \(\log(bwght)\):

\[\begin{equation} \log(bwght) =\beta_{0} +\beta_{1}faminc +u \end{equation}\]

Holding \(u\) fixed,

\[\begin{equation} \Delta \log(bwght) =\beta _{1} \Delta faminc \end{equation}\]

so, \[\begin{equation}\beta_{1} =\frac{ \Delta \log (bwght)}{ \Delta faminc} \end{equation}\]

Useful result from calculus:

\[\begin{equation}100 \cdot \Delta \log(bwght) \approx \% \Delta faminc \end{equation}\]

This means when \(\log(bwght) =\beta _{0} +\beta _{1}faminc +u\), we have a simple interpretation of \(\beta_{1}\):

\(100 \beta _{1} \approx \% \Delta wage\) when \(\Delta faminc =1\)

Why, you ask, is this \(100\times\beta_1\)? Well, technically it’s not actually 100%. It’s a rule of thumb we use. We treat logs as an approximate percent change. If we set \(\delta = 1\) for a unit change:

\[\begin{equation}E[lnY_0] = \beta_0 +\beta_1 X\end{equation}\] \[\begin{equation}E[lnY_1] = \beta_0 +\beta_1(X+1)\end{equation}\] \[\begin{equation}E[lnY_1]-E[lnY_0] = \beta_1(X+1) -\beta_1X\end{equation}\] \[\begin{equation}E[lnY_1]-E[lnY_0] = \beta_1\end{equation}\]

When you multiply \(\beta_1\) by 100, the approximation is \(E[lnY_1]-E[lnY_0] \approx \frac{E[Y_1]-E[Y_0]}{E[Y_0]}\).

For simplicity, let’s just drop the expectations and treat it as if there is no variance in \(Y_0\) and \(Y_1\). Using log-rules, \(lnY_0-lnY_1 = ln(\frac{Y_1}{Y_0}) = ln(\frac{Y_0}{Y_0} + \frac{Y_1-Y_0}{Y_0}) = ln(1+\frac{\Delta Y}{Y_0})\) This last part, \(\frac{\Delta Y}{Y_0})\) is nothing else but the percent change in Y divided by 100.

So, we get
\[\begin{equation} ln(1+\frac{\Delta}{Y_1})=\beta \end{equation}\]

We can exponentiate both sides and see the approximation: \(\frac{\Delta y}{y_1} = e^\beta-1 \approx \beta\)

This approximation comes from a k-th order Taylor series expansion of \(e^\beta\) around zero (technically, Maclaurin series):

\[\begin{equation} e^\beta \approx P_k = 1 + \beta+ \frac{\beta^2}{2!}+ \frac{\beta^3}{3!}+ \dots \end{equation}\]

We only use the linear approximation (and disregard the terms from the quadratic onward), it will be more accurate the smaller \(\beta\) is. This is fine for small changes, but you may want to report \(100*(e^\beta -1)\) instead:

Bias in percent change approximation

Note: A Taylor series expansion of any function is an infinite polynomial approximation of that function about a certain point. The more higher order terms we use, the more closely we approximate the original function further away from the point.

Remember, we are looking at non-linear relationship, so here are two forms of log-lin visualized

drawing

library("wooldridge", "stargazer", "tidyverse")
data(bwght)
loglin <- lm(log(bwght) ~ cigs+faminc, data = bwght)

#stata equivalent
# gen lnbwght = ln(bwght)
# reg lnbwght cigs faminc

sum_loglin <- summary(loglin)
sum_loglin

Call:
lm(formula = log(bwght) ~ cigs + faminc, data = bwght)

Residuals:
     Min       1Q   Median       3Q 
-1.62745 -0.08761  0.02148  0.12155 
     Max 
 0.82230 

Coefficients:
              Estimate Std. Error t value
(Intercept)  4.7439566  0.0098431 481.958
cigs        -0.0040326  0.0008593  -4.693
faminc       0.0008437  0.0002739   3.081
            Pr(>|t|)    
(Intercept)  < 2e-16 ***
cigs        2.96e-06 ***
faminc       0.00211 ** 
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.1883 on 1385 degrees of freedom
Multiple R-squared:  0.02646,   Adjusted R-squared:  0.02505 
F-statistic: 18.82 on 2 and 1385 DF,  p-value: 8.608e-09
#stata equivalent
#eststo loglin: reg lnbwght cigs faminc
 
cigsbeta <- exp(loglin$coefficients[2])-1
cigsbeta
        cigs 
-0.004024441 
faminc <- exp(loglin$coefficients[3])-1
faminc
      faminc 
0.0008441028 

For every additional dollar of family income leads to an increase in the baby’s birth weight by .08% (0.0008*100)

Log-log

We can use the log on both sides of the equation to get constant elasticity models. For example, if

\[\log(bwght) =\beta _{0} +\beta _{1} \log(faminc) +u\] then

\[\beta_{1} \approx \frac{ \% \Delta bwght}{ \% \Delta faminc}\]

The elasticity is free of units of \(bwght\) and \(faminc\).

We can also see this algebraically:

Take a small shift in X $\[$\log(bwght+ \Delta bwght) =\beta _{0} +\beta _{1} \log(faminc + \Delta faminc) +u\] $$

then subtract \(\log(bwght) =\beta _{0} +\beta _{1} \log(faminc) +u\) and you’ll get: \[\Delta bwght = \beta_1(\Delta lnfaminc) \] Solve for \(\beta_1\): \[\beta_1 = \frac{\Delta lnbwght}{\Delta lnbwght} \approxeq \frac{\Delta bwght /bwght}{\Delta faminc/ faminc}\] For a 1% unit increase (decrease) in X, we have \(\Delta𝑋=0.01(−0.01)\), and we expect a \(\beta_1\%\) increase (decrease) in Y

loglog <- lm(log(bwght) ~ cigs+log(faminc), data = bwght)
sum_loglog <- summary(loglog)
sum_loglog

Call:
lm(formula = log(bwght) ~ cigs + log(faminc), data = bwght)

Residuals:
     Min       1Q   Median       3Q 
-1.63374 -0.08711  0.02261  0.12132 
     Max 
 0.82254 

Coefficients:
              Estimate Std. Error t value
(Intercept)  4.7185937  0.0182445 258.631
cigs        -0.0040816  0.0008582  -4.756
log(faminc)  0.0162657  0.0055833   2.913
            Pr(>|t|)    
(Intercept)  < 2e-16 ***
cigs        2.18e-06 ***
log(faminc)  0.00363 ** 
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.1883 on 1385 degrees of freedom
Multiple R-squared:  0.02576,   Adjusted R-squared:  0.02435 
F-statistic: 18.31 on 2 and 1385 DF,  p-value: 1.417e-08

The estimated elasticity of bwght with respect to family income is about .016 or a 1% change in family income is associated with a .016% increase in birth weiht (To interpret this elasticity, we do not need to know \(bwght\) is in ounces while \(faminc\) is in thousands.)

It could be better to think in larger terms (who wants a 1% increase in income?)- a 10 percent increase in family income leads to an increase in birth weight by 1.6%

\(.016 (10) =1.6\) percent increase in family income.

How do you interpret the coefficient of cigs?

For every additional cigarette smoked on average per day is associated with a .4 % increase in birthweight.

How do you interpret the intercept?

Well, it’s trickier to interpret the log directly. The intercept is not measuring a change in values - so it’s not a percent change (there is no difference in logs). It’s much easier just to exponentiate the value. So, to interpret the intercept, we can exponentiate like so:

exp(loglog$coefficients)
(Intercept)        cigs log(faminc) 
112.0106236   0.9959267   1.0163987 

In this case, the intercept is 112.01 ounces. Leaving it in log units is kind of strange, because what are log units? Much better to exponentiate it to convert it back to understandable units.

The log-on-log case represents a multiplicative relationship between the original variables. For instance \[lny = \beta_0 +\beta_1lnx_1+\beta_2lnx_2+u_i\]

is equivalent to \[y = e^{\beta_0}x_1^{\beta_1}x_2^{\beta_2}e^{u} \] Very convenient! Think of a linearized Cobb-Douglas production function (macro)!

lin-log

In a lin log model,

\[bwght =\beta_{0} +\beta_{1} \log(faminc) +u\] then

\[\beta _{1} \approx \frac{ \Delta bwght}{ \Delta log(faminc)}\]

We can see this algebraically, too:

After a small shift in \(\Delta\)faminc in faminc: \[bwght = \beta_0 + \beta_1ln(faminc +\Delta faminc)\] Subtract this from our earlier regression, \(bwght =\beta_{0} +\beta_{1} \log(faminc) +u\)

and you get:

\[=\beta_1 \Delta lnfaminc\] Solve for \(\beta_1\) \[\beta_1 = \frac{\Delta bgwht}{\Delta lnfaminc} \approxeq \frac{\Delta bgwht}{\Delta faminc/faminc} = \] For 1 % increase (decrease) in X, we have a \(\Delta faminc =0.01(-0.01)\), and we expect a 0.01 \(\beta_1\) increase (decrease) in Y

We can see the non-linear relationship for a log-lin with a positive ln(x) and negative ln(x):

drawing drawing

linlog <- lm(bwght ~ cigs+log(faminc), data = bwght)
sum_linlog <- summary(linlog)
sum_linlog

Call:
lm(formula = bwght ~ cigs + log(faminc), data = bwght)

Residuals:
    Min      1Q  Median      3Q     Max 
-96.753 -11.716   0.701  13.208 150.070 

Coefficients:
             Estimate Std. Error t value
(Intercept) 113.99070    1.94392  58.640
cigs         -0.46723    0.09144  -5.110
log(faminc)   1.85072    0.59489   3.111
            Pr(>|t|)    
(Intercept)  < 2e-16 ***
cigs        3.68e-07 ***
log(faminc)   0.0019 ** 
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 20.07 on 1385 degrees of freedom
Multiple R-squared:  0.02951,   Adjusted R-squared:  0.02811 
F-statistic: 21.06 on 2 and 1385 DF,  p-value: 9.796e-10

For every additional $1000 in family income, birth weight will increase by .018 % (1.8/100)

or rather, for every $10,000 increase in birth weight is associated with 18 ounces ((1.8/100)*1000)

Let’s compare our estimates of the models

library("stargazer")

Please cite as:

Hlavac, Marek (2018). stargazer: Well-Formatted Regression and Summary Statistics Tables. R package version 5.2.2. https://CRAN.R-project.org/package=stargazer

linlin <- lm(bwght ~ cigs + faminc, data = bwght)
sum_linlin <- summary(linlin)

stargazer( loglog, loglin, linlog, linlin, type = "html",
           results = 'asis',message = FALSE, echo = FALSE, notes.append = FALSE, header = FALSE, single.row = TRUE)
the condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changed
Dependent variable:
log(bwght) bwght
(1) (2) (3) (4)
cigs -0.004*** (0.001) -0.004*** (0.001) -0.467*** (0.091) -0.463*** (0.092)
log(faminc) 0.016*** (0.006) 1.851*** (0.595)
faminc 0.001*** (0.0003) 0.093*** (0.029)
Constant 4.719*** (0.018) 4.744*** (0.010) 113.991*** (1.944) 116.974*** (1.049)
Observations 1,388 1,388 1,388 1,388
R2 0.026 0.026 0.030 0.030
Adjusted R2 0.024 0.025 0.028 0.028
Residual Std. Error (df = 1385) 0.188 0.188 20.066 20.063
F Statistic (df = 2; 1385) 18.310*** 18.822*** 21.058*** 21.274***
Note: p<0.1; p<0.05; p<0.01
asis
FALSE
FALSE

What can we compare?

The SER (standard error of the regression) is in the dependent units. This means that we can compare the fit of the models lin-log and lin-log models, but not any of the models that have the log in the dependent variables.

In addition, the \(R\)-squared is not directly comparable. The total variation (SSTs) in \(bweight_{i}\) and \(l bweight_{i}\) that we must explain are completely different.

A handy reminder of interpreting coefficients is:

Model Dep. Var Indep. Var \(\beta_1\)
Lin-Lin y x \(\Delta y=\beta_1 \Delta x\)
Lin-Log y log(x) \(\Delta y=(\beta_1/100\%) \Delta x\)
Log-Lin log(y) x \(\%\Delta y=(100\beta_1) \Delta x\) technically should be \(100 * (e^\beta-1) \Delta x\)
Log-Log log(y) log(x) \(\Delta \%y=\beta_1\Delta x\)

The possibility of using the natural log to get non-linear relationships between \(y\) and \(x\) raises a question: What do we mean now by ``linear’’ regression?

The answer is that the model is linear in the , \(\beta _{0}\) and \(\beta _{1}\). We can use any transformations of the dependent and independent to get interesting interpretations for the parameters.

Standardized coefficients

Confusingly, a beta coefficient is a standardized coefficient. We use beta hat to denote our OLS estimate. For the sake of this course, we will continue using the term standardized coefficient when we standardize y and each \(x_j\) by subtracting its mean and dividing by its sample standard deviation.

This can be useful when some of the \(x_j\) or y have units that are not easily understood. So, for example, we might not have a good sense for how important is an increase in a test score by one point. Using logs gives us percentage effects, but we do not always want to do that.

It is often useful to ask the following question, which allows us to see how important an effect is relative to the population: “How many standard deviations will y change when \(x_j\) increases by one standard deviation?”

When you standardize, there is no beta coefficient for the intercept because the intercept is zero when all variables have zero sample averages.

library("dplyr")

data(attend)
# If you want to standardize your own values, you can do so as such. I am standardizing GPA and ACT in this case and creating a NEW dataframe. This will replace the existing columns - so be aware of that in this method!
attendstd <- attend %>% mutate_at(c('priGPA', 'ACT'), ~(scale(.) %>% as.vector))

attend_std <- lm(stndfnl ~ missed+priGPA+ACT, data = attendstd)

summary(attend_std)

Call:
lm(formula = stndfnl ~ missed + priGPA + ACT, data = attendstd)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.2339 -0.5528 -0.0329  0.5884  2.3303 

Coefficients:
             Estimate Std. Error t value
(Intercept)  0.127214   0.055064   2.310
missed      -0.016668   0.007402  -2.252
priGPA       0.219178   0.042640   5.140
ACT          0.294122   0.039034   7.535
            Pr(>|t|)    
(Intercept)   0.0212 *  
missed        0.0247 *  
priGPA      3.60e-07 ***
ACT         1.57e-13 ***
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.8862 on 676 degrees of freedom
Multiple R-squared:  0.2013,    Adjusted R-squared:  0.1978 
F-statistic: 56.79 on 3 and 676 DF,  p-value: < 2.2e-16

The coefficient on priGPA is larger than on ACT by almost a factor of five. But does this mean priGPA has the more important effect?

An increase in one sd of priGPA increases final by about .219 sds while a one sd increase in ACT increases final by about .294 sds, which is a larger movement in the distribution of final exam scores.

Quadratic/Polynomial Functions

Using the log of an independent variable is one way to get a diminishing effect. But sometimes it is not flexible enough.

Models with quadratics can deliver increasing or decreasing effects. Plus, they contain the constant effect as a special case, which can be easily tested.

Models also allow for a turning point, which is sometimes of interest. (For example, what is the optimal number of students at a high school for high school performance?)

Consider the model

\[y = β_0 + β_1x_1 + β_2x_1^2 + u\]

There is only a single explanatory variable, x, but two regressors, \(x_1, x_2\).

The slope of y with respect to x depends on \(\beta_1\) and \(\beta_2\), and the value of x: $ = _1 + 2_2x$ holding u fixed

Estimation is straightforward. We just define a new variable, \(x^2\), and include it along with x as a regressor.

Having estimated the coefficients we write \[ \hat{y} = \hat{\beta_0}+\hat{\beta_1}x+\hat{\beta_2}x^2 \]

\[ \frac{\Delta{\hat{y}}}{\Delta X} \approx \hat{\beta_1}+\hat{\beta_2}2X \]

Cases

  1. If \(\hat{\beta_1} > 0\) and \(\hat{\beta_2} < 0\), the slope is initially positive, but it decreases as x increases. The function has a hump shape and turns at the value

\[ \displaystyle\left\lvert x^* = {\frac{\hat{\beta_1}}{2 \hat{\beta_2}}} \right\rvert \]

the maximum of the function. After the value x∗, the slope is negative.

library(tidyverse)
quadratic <- function(x){x-x^2}

#plot it
ggplot(data.frame(x = c(-15,15)), aes(x = x)) +
  stat_function(fun = quadratic) + xlim(c(-15, 15)) 

  1. If \(\hat{\beta_1} < 0\) and \(\hat{\beta_2} > 0\), the slope is initially negative, but it increases (gets less negative) as x increases. The function has a U shape and turns at the x∗ given above. But now x∗ is the minimum of the function. Once \(x > x∗\), the slope is positive.
quadratic <- function(x){-x+x^2}

#plot it
ggplot(data.frame(x = c(-15,15)), aes(x = x)) +
  stat_function(fun = quadratic) + xlim(c(-15, 15)) 



#curve(-x+x^2 , from=1, to=10, n=300, xlab="xvalue", ylab="yvalue", 
 #            col="blue", lwd=2, main=expression(hat(beta[1])<0 ~ "," ~hat(beta[2])>0))

In Cases 1 and 2, we should ask: Does the turning point makes sense? If it does not make sense for the slope to change signs, does the sign change happen only at an extreme value of x?

  1. If \(\hat{\beta_1} > 0\) and \(\hat{\beta_2} > 0\), the slope (\(\hat{\beta_1}+2\hat{\beta_2}x\)) is always positive and increases with x. The turning point occurs at a negative value of x. (In practice, less common than Case 1.)
library(tidyverse)
quadratic <- function(x){x+x^2}


curve(  x+x^2 , from=1, to=10, n=300, xlab="xvalue", ylab="yvalue", 
             col="blue", lwd=2, main=expression(hat(beta[1])>0 ~ "," ~hat(beta[2])>0))

  1. If \(\hat{\beta_1} < 0\) and \(\hat{\beta_2} < 0\), the slope is always negative and becomes more negative (increases in absolute value) as x in creases. The turning point is negative.

Adding additional explanatory variables changes nothing of the calculations, except for giving a ceteris paribus interpretation.


#plot it
curve(  -x-x^2 , from=1, to=10, n=300, xlab="xvalue", ylab="yvalue", 
             col="blue", lwd=2, main=expression(hat(beta[1])>0 ~ "," ~hat(beta[2])>0))

data(wage1)
wage1$exper2 <- wage1$exper^2
wage_square <- lm(log(wage) ~educ + exper + exper2 , data = wage1)
summary(wage_square)

Call:
lm(formula = log(wage) ~ educ + exper + exper2, data = wage1)

Residuals:
     Min       1Q   Median       3Q 
-1.96387 -0.29375 -0.04009  0.29497 
     Max 
 1.30216 

Coefficients:
              Estimate Std. Error t value
(Intercept)  0.1279975  0.1059323   1.208
educ         0.0903658  0.0074680  12.100
exper        0.0410089  0.0051965   7.892
exper2      -0.0007136  0.0001158  -6.164
            Pr(>|t|)    
(Intercept)    0.227    
educ         < 2e-16 ***
exper       1.77e-14 ***
exper2      1.42e-09 ***
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.4459 on 522 degrees of freedom
Multiple R-squared:  0.3003,    Adjusted R-squared:  0.2963 
F-statistic: 74.67 on 3 and 522 DF,  p-value: < 2.2e-16

The estimated return to education is 9.0%. The model assumes this is the same for all years of experience and education.

By contrast, each year of experience is worth less than the preceding year. The slope is, using calculus – just take the derivative with respect to exper – is \[\begin{equation} \frac{\Delta \hat{lwage}}{\Delta exper} \approx .041 − 2(.0007)exper = .041 − .0014exper \end{equation}\]

Can think of 12.7% (the \(\beta_0\)) as approximately the return to the first year of experience – essentially starting off in the workforce. The return in going from 10 to 11 is about \(.041 − .0396*10 = -.355\) or 2.7%.

We could be more precise and not use a calculus approximation: \([.041(11) − .0007(11)^2] − [.041(10) − .0007(10)^2] \approx 2.63\), which is reasonably close.

Because the quadratic model is more complicated to interpret and explain, we should make sure there is good statistical evidence for keeping \(x_2\) (exper2) in the equation.

So, we test the null that the equation is linear in exper against the alternative that it is quadratic: \[\begin{equation} H_0 = \beta_{exper2} = 0 \end{equation}\] \[\begin{equation} H_A = \beta_{exper2} \neq 0 \end{equation}\]

Important: \(β_{exper}\) is not restricted. So we use a t test on exper2.

The t in this example is -6.164 with two-sided p-value = .0001, so we reject H0 at the 5% level. It seems a good idea to keep exper2 in the equation.

However, if we want to test if experience has an effect on wages: This would be \[\begin{equation} H_0: \beta_{exper} = 0, \beta_{exper^2} = 0 \end{equation}\] We would use an F test. But usually, if the quadratic term is insignificant, we go back to a linear model.

We can also find the “peak” or “trough” by setting our FOC (first order conditions) to 0 and solving for X.

\(0 = .041 − 2(.0007)exper\)

\(exper = .041/.0014 = 29.29\)

After working for 29.29 years, the marginal increase of salary begins to decline.

With calculus, we can also say something about whether the effect is going to marginally increase or marginally decrease. We just take the second derivative of our marginal effects equation and see if the result is positive or negative. This basically tells us if after the peak or trough, does the value go up or down. And we can see that the second derivative of exper is negative.

But, even more simply, we can just look at the sign of the squared term. A positive term will tell us that the marginal effect increases, while a negative term will tell us that the marginal effect decreases.

Let’s graphically visualize these results:


library(wooldridge)
#install.packages("margins")
library(margins)


lm(log(wage) ~educ + stats::poly(exper, 2) , data = wage1)

Call:
lm(formula = log(wage) ~ educ + stats::poly(exper, 2), data = wage1)

Coefficients:
           (Intercept)  
               0.48803  
                  educ  
               0.09037  
stats::poly(exper, 2)1  
               3.07380  
stats::poly(exper, 2)2  
              -2.78645  
# we have to use the poly function to get the correct marginal effects graph

wage_square <- lm(log(wage) ~educ + exper + I(exper^2) , data = wage1)

summary(wage_square)

Call:
lm(formula = log(wage) ~ educ + exper + I(exper^2), data = wage1)

Residuals:
     Min       1Q   Median       3Q 
-1.96387 -0.29375 -0.04009  0.29497 
     Max 
 1.30216 

Coefficients:
              Estimate Std. Error t value
(Intercept)  0.1279975  0.1059323   1.208
educ         0.0903658  0.0074680  12.100
exper        0.0410089  0.0051965   7.892
I(exper^2)  -0.0007136  0.0001158  -6.164
            Pr(>|t|)    
(Intercept)    0.227    
educ         < 2e-16 ***
exper       1.77e-14 ***
I(exper^2)  1.42e-09 ***
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.4459 on 522 degrees of freedom
Multiple R-squared:  0.3003,    Adjusted R-squared:  0.2963 
F-statistic: 74.67 on 3 and 522 DF,  p-value: < 2.2e-16
cplot(wage_square, "exper")


# We can take the average of the marginal effect with:
summary(margins(wage_square, variables = "exper"))

#we can also extract the marginal effect in a table:
dydx(wage1, wage_square, variable = "exper")

#at specific values
summary(margins(wage_square, at = list(exper = c(10, 15, 20, 25, 30, 35, 40)), variables = "exper"))

mean(wage1$exper)
[1] 17.01711

Recall that if you have multiple variables that are highly correlated that your inference will change. Well, that’s no different here - you can imagine that \(x\) and \(x^2\) are highly correlated

To see if experience has a statistically significant effect on wages, we must conduct an f test on all of the terms associated with experience.

Let’s do that f-test

library(car)
Loading required package: carData

Attaching package: ‘car’

The following object is masked from ‘package:dplyr’:

    recode

The following object is masked from ‘package:purrr’:

    some
linearHypothesis(wage_square, c("exper=0", "I(exper^2)=0"))
Linear hypothesis test

Hypothesis:
exper = 0
I(exper^2) = 0

Model 1: restricted model
Model 2: log(wage) ~ educ + exper + I(exper^2)

  Res.Df    RSS Df Sum of Sq      F
1    524 120.77                    
2    522 103.79  2    16.979 42.696
     Pr(>F)    
1              
2 < 2.2e-16 ***
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Indeed, experience has a statistically significant effect. We reject the null at the 1% level.

We can also see how the linear vs. quadratic fit changes

data(wage1)

#Let's graph the simple regression line differences

library(tidyverse)
ggplot(wage1, aes(x=exper, y=wage))+
  geom_point() +
  stat_smooth(aes(y = wage),method = "lm", formula = y ~ x , color= "red") +
  stat_smooth(aes(y=wage), method = "lm", formula = y ~ x + I(x^2)) 



#We can add controls and look at the differences in the regression
wage_lin <- lm(wage ~educ + exper, data = wage1)
wage_quad <- lm(wage ~educ + exper +I(exper^2), data = wage1)

Interaction Terms

The quadratic is not very different from interaction terms in mechanical terms, you just have to be careful of interpretation and testing - because the two terms depend on one another.

Suppose we have two explanatory variables and start with the usual model:

\[y = β_0 + β_1x_1 + β_2x_2 + u\]

The partial effect of \(x_1\) on y is \(β_1\) and the PE of \(x_2\) on y is \(β_2\). Even if we add quadratics, the model has a potentially important restriction: the partial effect of \(x_1\) never depends on \(x_2\), and vice versa.

Sometimes it is natural to think the partial effect of one variable, say education, could depend on the level of another variable, say intelligence.

Let’s add an interaction term:

\(y=β_0 +β_1x_1 +β_2x_2 +β_3x_1x_2 +u\)

Holding \(x_2\) (and u) fixed, the partial effect of \(x_1\) on y is:

\[\begin{equation} \frac{\Delta y}{\Delta x_1} =\beta_1 + \beta_3x_2 \end{equation}\]

so that the effect of \(x_1\) depends on \(x_2\) unless \(\beta_3 = 0\): \[\begin{equation} \frac{\Delta y}{\Delta x_2} =\beta_2 + \beta_3x_1 \end{equation}\]

The null hypothesis \(H_0 : β_3 = 0\) is the same as saying the partial effects are constant. It should be tested. If it cannot be rejected at a small significance level (smaller than 5%), it is not worth complicating the model.

It is easy to get confused in models with interactions. From

\[\begin{equation} \frac{\Delta y}{\Delta x_1} =\beta_1 + \beta_3x_2 \end{equation}\]

we see that \(β_1\) is now the PE of \(x_1\) on y when \(x_2\) =0. But \(x_2 =0\) may be very far from a legitimate, or at least interesting, part of the population. A similar comment holds for \(β_1\).

Two interesting parameters are the PEs evaluated at the mean of the other variable:

\[\begin{equation} \gamma_1 = \beta_1 +\beta_3 \mu_2 \end{equation}\]

\[\begin{equation} \gamma_2 = \beta_2 +\beta_3 \mu_1 \end{equation}\]

We will estimate these as:

\[\begin{equation} \hat{\gamma_1} = \hat{\beta_1} +\hat{\beta_3} \bar{x}_2 \end{equation}\]

\[\begin{equation} \hat{\gamma_2} = \hat{\beta_2} +\hat{\beta_3} \bar{x}_1 \end{equation}\]

where \(\bar{x}_2\) and \(\bar{x}_1\) are the sample averages and the \(\hat{\beta_2}\) are the OLS estimates.

It is often easier to let a regression compute \(\hat{\gamma_1}\) and \(\hat{\gamma_2}\), and to get appropriate standard errors. We can write in the population \[\begin{equation} y = \alpha_0 + \gamma_1 x_1 + \gamma_2 x_2 + \beta_3(x_1 - \mu_1) (x_2 - \mu_2) +u \end{equation}\]

In other words, we subtract the means before creating the interactions. The regression we run is

\(y_i\) on \(x_{i1}\), \((x_{i1} - \bar{x_1})(x_{i2} - \bar{x_2}), i = 1, \dots,n\)

The intercept changes, too, but this is not important. The coefficient on the interaction does not change.

Let’s see it:

First model the interaction is educ*IQ

wage_lin <- lm(log(wage) ~educ + IQ  , data = wage2)
summary(wage_lin)

Call:
lm(formula = log(wage) ~ educ + IQ, data = wage2)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.01601 -0.24367  0.03359  0.27960  1.23783 

Coefficients:
             Estimate Std. Error t value             Pr(>|t|)
(Intercept) 5.6582876  0.0962408  58.793 < 0.0000000000000002
educ        0.0391199  0.0068382   5.721        0.00000001428
IQ          0.0058631  0.0009979   5.875        0.00000000587
               
(Intercept) ***
educ        ***
IQ          ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3933 on 932 degrees of freedom
Multiple R-squared:  0.1297,    Adjusted R-squared:  0.1278 
F-statistic: 69.42 on 2 and 932 DF,  p-value: < 0.00000000000000022
wage_int <- lm(log(wage) ~educ + IQ + educ*IQ , data = wage2)
summary(wage_int)

Call:
lm(formula = log(wage) ~ educ + IQ + educ * IQ, data = wage2)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.01350 -0.24251  0.03254  0.27532  1.23995 

Coefficients:
             Estimate Std. Error t value            Pr(>|t|)    
(Intercept) 5.8383697  0.5683982  10.272 <0.0000000000000002 ***
educ        0.0252660  0.0436352   0.579               0.563    
IQ          0.0041307  0.0054808   0.754               0.451    
educ:IQ     0.0001318  0.0004099   0.321               0.748    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3935 on 931 degrees of freedom
Multiple R-squared:  0.1298,    Adjusted R-squared:  0.1269 
F-statistic: 46.27 on 3 and 931 DF,  p-value: < 0.00000000000000022

Now, let’s see the regression with mean adjusted values.


#Generate mean values for each variable
data(wage2)

mean_educ = mean(wage2$educ)

summary(wage2$IQ)

Min. 1st Qu. Median Mean 3rd Qu. Max. 50.0 92.0 102.0 101.3 112.0 145.0

mean_iq = mean(wage2$IQ)

#create a new variable using mutate that is the mean adjusted value for educ and IQ
wage2 <-mutate(wage2, mean_educ_adj  = educ-mean_educ, mean_iq_adj = IQ-mean_iq)

#run the regression with the mean adjusted regression
wage_int_meanadj <- lm(log(wage) ~educ + IQ + mean_educ_adj*mean_iq_adj  , data = wage2)


library("stargazer")
stargazer(wage_int_meanadj, wage_int, type = "html", 
          results = 'asis',message = FALSE, echo = FALSE, notes.append = FALSE, header = FALSE, single.row = TRUE)
the condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changednumber of rows of result is not a multiple of vector length (arg 2)
Dependent variable:
log(wage)
(1) (2)
educ 0.039*** (0.007) 0.025 (0.044)
IQ 0.006*** (0.001) 0.004 (0.005)
mean_educ_adj
mean_iq_adj
mean_educ_adj:mean_iq_adj 0.0001 (0.0004)
educ:IQ 0.0001 (0.0004)
Constant 5.659*** (0.096) 5.838*** (0.568)
Observations 935 935
R2 0.130 0.130
Adjusted R2 0.127 0.127
Residual Std. Error (df = 931) 0.394 0.394
F Statistic (df = 3; 931) 46.269*** 46.269***
Note: p<0.1; p<0.05; p<0.01
asis
FALSE
FALSE

You can see that the interaction term is the same between the mean centered and uncentered regressions.

The interaction term is not statistically significant. And similarly, we can see that when centering has been done, these estimates are much closer to the regression without interactions (0.0391199, 0.0058631 compared to 0.0386104, 0.0059052 )

The positive coefficient on the interaction means that the return to education is higher for people with higher ability.

The estimated partial effect of educ is \(0.0386+0.0001*IQ\) If someone has an IQ that is 10 above the mean, the return to education is: \(0.0386+0.0001(10-101.28) = .0294\) or 2.94%

If someone has an IQ that is 10 below the mean, the return to education is: \(0.0386+0.0001(-10-101.28) = .0274\) or 2.74%

If we can believe these estimates, schooling is worth more for those with higher intelligence.

Dummy Variables

Dummy variables are essentially, differences in means (and this will be VERY important for Diff-Diff) regressions.

Say, we are interested in the gender wage gap, and we estimate a simple regression:

\[\begin{equation} wage = \beta_0 +\gamma_0female +u \end{equation}\]

Where \(E(u|female = 1)\) and therefore,

\[\begin{equation} E(wage|female) = \beta_0 + \gamma_0 female \end{equation}\]

There are only two values for female, 0 and 1.

\[\begin{equation} E(wage|female = 0) = \beta_0 \end{equation}\]

\[\begin{equation} E(wage|female = 1) = \beta_0 + \gamma_0 female \end{equation}\]

We can then write,

\[\begin{equation} \gamma_0 = E(wage|female = 1) - E(wage|female = 0) \end{equation}\]

And that’s just the difference in wage between women and men.

So \(\gamma_0\) is not a slope. It’s just a difference in average outcomes between two groups.

The population relationship is mimicked in the simple regression estimates.

\[\begin{equation} \hat{\beta_0}= \bar{wage_m} \end{equation}\] \[\begin{equation} \hat{\beta_0} + \hat{\gamma_0}= \bar{wage_f} \end{equation}\] \[\begin{equation} \hat{\gamma_0}= \bar{wage_f}-\bar{wage_m} \end{equation}\]

where \(\bar{wage_m}\) is the average wage for men in the sample and \(\bar{wage_f}\) is the average wage for women in the sample.

data(wage1)

summary(lm(wage ~ female, data = wage1))

Call:
lm(formula = wage ~ female, data = wage1)

Residuals:
    Min      1Q  Median      3Q     Max 
-5.5995 -1.8495 -0.9877  1.4260 17.8805 

Coefficients:
            Estimate Std. Error t value
(Intercept)   7.0995     0.2100  33.806
female       -2.5118     0.3034  -8.279
            Pr(>|t|)    
(Intercept)  < 2e-16 ***
female      1.04e-15 ***
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 3.476 on 524 degrees of freedom
Multiple R-squared:  0.1157,    Adjusted R-squared:  0.114 
F-statistic: 68.54 on 1 and 524 DF,  p-value: 1.042e-15

The estimated effect is large, women earn about $2.5 less than men.

The simple regression is a comparison of means. Where we are testing

\(H_0: \mu_f = \mu_m\)

where μf is the population average wage for women and μm is the population average wage for men. The t statistic and confidence interval are directly reported.

We can see the value is 8.279 and strongly reject the null.

The estimate \(\hat{\gamma_0} = −2.5\) does not control for factors that should affect wage, such as workforce experience and schooling. If women have, on average, less experience and less college, that could explain the difference in average wages.

If we just control for experience, the model written in expected value form is \(E(wage|female,exper)=β_0 +δ_0female+β_1exper\)

where now \(δ_0\) measures the gender difference when we hold fixed exper.

Another way to write \(δ_0\): \[\begin{equation} δ_0 =E(wage|female,exper_0)−E(wage|male,exper_0) \end{equation}\] where \(exper_0\) is any level of experience that is the same for the woman and man.

data(wage1)

summary(lm(wage ~ female+exper, data = wage1))

Call:
lm(formula = wage ~ female + exper, data = wage1)

Residuals:
   Min     1Q Median     3Q    Max 
-5.961 -2.031 -0.899  1.440 17.573 

Coefficients:
            Estimate Std. Error t value
(Intercept)  6.62688    0.28625  23.151
female      -2.48142    0.30228  -8.209
exper        0.02692    0.01114   2.417
            Pr(>|t|)    
(Intercept)  < 2e-16 ***
female      1.75e-15 ***
exper          0.016 *  
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 3.46 on 523 degrees of freedom
Multiple R-squared:  0.1254,    Adjusted R-squared:  0.1221 
F-statistic: 37.51 on 2 and 523 DF,  p-value: 6.008e-16

There is still a difference of about $2.27, which is smaller than when exper is not controlled for, but still very large and very statistically significant.

This model imposes a common slope on exper for men and women (.50) - Only the intercepts differ

intercept differ We can add additional controls, as well.

summary(lm(wage ~ female+educ+exper+married, data = wage1))

Call:
lm(formula = wage ~ female + educ + exper + married, data = wage1)

Residuals:
    Min      1Q  Median      3Q     Max 
-6.4057 -1.9042 -0.5982  1.1454 14.6545 

Coefficients:
            Estimate Std. Error t value
(Intercept) -1.79066    0.75121  -2.384
female      -2.06710    0.27221  -7.594
educ         0.58332    0.05166  11.292
exper        0.05567    0.01106   5.035
married      0.66024    0.29685   2.224
            Pr(>|t|)    
(Intercept)   0.0175 *  
female      1.45e-13 ***
educ         < 2e-16 ***
exper       6.59e-07 ***
married       0.0266 *  
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 3.066 on 521 degrees of freedom
Multiple R-squared:  0.3158,    Adjusted R-squared:  0.3105 
F-statistic: 60.12 on 4 and 521 DF,  p-value: < 2.2e-16

Let’s say you estimate:

\[\begin{equation} wage = \beta_0 + \beta_1 male \end{equation}\]

What is the expected sign (given that you know information from the prior regression)?

Note: as you may recall, if you put female and male into the same regression, you will have a dummy variable trap.

Dummy variables with Multiple Categories

Suppose in the wage example we have two qualitative variables, gender and maritial status. Call these female and married.

We can define four exhaustive and mutually exclusive groups. These are married males (marrmale), married females (marrfem), single males (singmale), and single females (singfem).

Note that we can define each of these dummy variables in terms of female and married:

\[\begin{equation} marrmale = married (1-female) \end{equation}\]

\[\begin{equation} marrfem = married * female \end{equation}\]

\[\begin{equation} singmale = (1-married)(1-female) \end{equation}\]

\[\begin{equation} singfem = (1-married)female \end{equation}\]

We can allow each of the four groups to have a different intercept by choosing a base group and then including dummies for the other three groups.

So, if we choose single males as the base group, we include marrmale, marrfem, and singfem in the regression.

The coefficients on these variabels are relative to single men.

With lwage as the dependent variable, we can give them a percentage change interpretation.

wage1 <-mutate(wage1, marrmale = married*(1-female),   marrfem = married*female, singmale = (1-married)*(1-female), singfem = (1-married)*female)

summary(lm(log(wage) ~ marrmale +marrfem +singfem +educ +stats::poly(exper,2) + stats::poly(tenure,2), data = wage1))

Call:
lm(formula = log(wage) ~ marrmale + marrfem + singfem + educ + 
    stats::poly(exper, 2) + stats::poly(tenure, 2), data = wage1)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.89697 -0.24060 -0.02689  0.23144  1.09197 

Coefficients:
                         Estimate Std. Error t value             Pr(>|t|)    
(Intercept)              0.630856   0.093162   6.772      0.0000000000347 ***
marrmale                 0.212676   0.055357   3.842             0.000137 ***
marrfem                 -0.198268   0.057835  -3.428             0.000656 ***
singfem                 -0.110350   0.055742  -1.980             0.048272 *  
educ                     0.078910   0.006694  11.787 < 0.0000000000000002 ***
stats::poly(exper, 2)1   1.074061   0.504030   2.131             0.033565 *  
stats::poly(exper, 2)2  -2.090136   0.431213  -4.847      0.0000016591606 ***
stats::poly(tenure, 2)1  2.569781   0.471069   5.455      0.0000000759593 ***
stats::poly(tenure, 2)2 -0.945818   0.410235  -2.306             0.021531 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3933 on 517 degrees of freedom
Multiple R-squared:  0.4609,    Adjusted R-squared:  0.4525 
F-statistic: 55.25 on 8 and 517 DF,  p-value: < 0.00000000000000022
summary(lm(log(wage) ~ female+married+ female*married +educ +stats::poly(exper,2) + stats::poly(tenure,2), data = wage1))

Call:
lm(formula = log(wage) ~ female + married + female * married + 
    educ + stats::poly(exper, 2) + stats::poly(tenure, 2), data = wage1)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.89697 -0.24060 -0.02689  0.23144  1.09197 

Coefficients:
                         Estimate Std. Error t value             Pr(>|t|)    
(Intercept)              0.630856   0.093162   6.772      0.0000000000347 ***
female                  -0.110350   0.055742  -1.980             0.048272 *  
married                  0.212676   0.055357   3.842             0.000137 ***
educ                     0.078910   0.006694  11.787 < 0.0000000000000002 ***
stats::poly(exper, 2)1   1.074061   0.504030   2.131             0.033565 *  
stats::poly(exper, 2)2  -2.090136   0.431213  -4.847      0.0000016591606 ***
stats::poly(tenure, 2)1  2.569781   0.471069   5.455      0.0000000759593 ***
stats::poly(tenure, 2)2 -0.945818   0.410235  -2.306             0.021531 *  
female:married          -0.300593   0.071767  -4.188      0.0000330208526 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3933 on 517 degrees of freedom
Multiple R-squared:  0.4609,    Adjusted R-squared:  0.4525 
F-statistic: 55.25 on 8 and 517 DF,  p-value: < 0.00000000000000022

What if we want to compare married women and single women?

Just plug in the correct set of zeros and ones. slope for married women = .63 − .198 (.432) slope for single women = .63 − .11 (.52) difference = −.198 − (−.110) = −.088 so married women earn about 8.8% less than single women (controlling for other factors).

We cannot tell from the previous output whether this difference is statistically significant (you can calculate this knowing that the difference between two variances is the sum of the variance, thus \(\sqrt{se_{marrfem} + se_{singfem}}\)

No matter which group we choose as the base group, we include only three of the four dummy variables. If we include all four we fall into the dummy variable trap.

Incidentally, in this data set, gender, marrital status, education, experience, and tenure explain about 45% (using \(R^2\)) of the variation in lwage.

Incorporating ordinal variables

Let’s take an example using the dataset beauty which includes a ranking of physical attractiveness of each man or woman, on a scale of 1 to 5, with 5 being “strikingly beautiful or handsome.” This is a subset of the data used in Hamermesh and Biddle (1994, American Economic Review).

As we move up the scale from 1 to 5, why should a one-unit increase mean the same amount of “beauty”?

The “looks” variable is what we call an ordinal variable: we know that the order of outcomes conveys information (5 is better than 4, and 2 is better than 1) but we do not know that the difference between 5 and 4 is the same as 2 and 1.

Let’s take a look at the data

data(beauty)
table(beauty$looks)

  1   2   3   4   5 
 13 142 722 364  19 

Very few people are at the extreme values 1 and 5 (less than 1% each). It makes sense to combine into three categories: below average (belavg), average, and above average (abvavg).

library(janitor)

Attaching package: ‘janitor’

The following objects are masked from ‘package:stats’:

    chisq.test, fisher.test
beauty <- mutate(beauty, belowav = if_else(looks <= 2, 1,0), abovav =if_else(looks >= 4,1,0))
tabyl(beauty$belowav, show_na = TRUE)
 beauty$belowav    n   percent
              0 1105 0.8769841
              1  155 0.1230159
tabyl(beauty$abovav, show_na = TRUE)
 beauty$abovav   n   percent
             0 877 0.6960317
             1 383 0.3039683

12.5% of people are “below average” and 30.3% have above average looks - everyone else has "average looks (looks =3)

Take average as the base group.

summary(lm(lwage ~belowav+ abovav, data = beauty))

Call:
lm(formula = lwage ~ belowav + abovav, data = beauty)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.67849 -0.37516  0.01673  0.38115  2.70025 

Coefficients:
            Estimate Std. Error t value             Pr(>|t|)    
(Intercept)  1.69830    0.02200  77.183 < 0.0000000000000002 ***
belowav     -0.20879    0.05234  -3.989            0.0000701 ***
abovav      -0.04544    0.03737  -1.216                0.224    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.5912 on 1257 degrees of freedom
Multiple R-squared:  0.01254,   Adjusted R-squared:  0.01097 
F-statistic: 7.985 on 2 and 1257 DF,  p-value: 0.0003583

Controlling for no other factors, those with below average looks earn about 20.8% less than those with average looks. The t statistic is very significant (p- value is super low).

Those with above average looks are estimated to earn about 4.5% less than those with average looks, but the p-value is .264. So there is little evidence the effect is different from zero.

Now control for some other factors, including gender and education.

summary(lm(lwage ~belowav+ abovav+educ+stats::poly(exper,2), data = beauty))

Call:
lm(formula = lwage ~ belowav + abovav + educ + stats::poly(exper, 
    2), data = beauty)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.6520 -0.3104  0.0203  0.3158  2.8213 

Coefficients:
                        Estimate Std. Error t value             Pr(>|t|)    
(Intercept)             0.820891   0.074791  10.976 < 0.0000000000000002 ***
belowav                -0.180063   0.046163  -3.901             0.000101 ***
abovav                 -0.012913   0.033455  -0.386             0.699577    
educ                    0.068769   0.005792  11.873 < 0.0000000000000002 ***
stats::poly(exper, 2)1  7.715889   0.535428  14.411 < 0.0000000000000002 ***
stats::poly(exper, 2)2 -3.427207   0.526097  -6.514       0.000000000105 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.5204 on 1254 degrees of freedom
Multiple R-squared:  0.2368,    Adjusted R-squared:  0.2338 
F-statistic: 77.81 on 5 and 1254 DF,  p-value: < 0.00000000000000022

The effect of having below average looks is now about 18% lower salary (on average). Above average looks is still statistically insignificant and gets smaller in magnitude.

Good practice to look at all coefficients to see if the signs and magnitudes make sense. They do, although the premium for males is very large.

summary(lm(lwage ~ looks+educ+stats::poly(exper,2), data = beauty))

Call:
lm(formula = lwage ~ looks + educ + stats::poly(exper, 2), data = beauty)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.62220 -0.31622  0.02116  0.31609  2.78775 

Coefficients:
                        Estimate Std. Error t value             Pr(>|t|)    
(Intercept)             0.602116   0.095330   6.316       0.000000000371 ***
looks                   0.062068   0.021923   2.831              0.00471 ** 
educ                    0.068369   0.005813  11.762 < 0.0000000000000002 ***
stats::poly(exper, 2)1  7.885959   0.535735  14.720 < 0.0000000000000002 ***
stats::poly(exper, 2)2 -3.421359   0.527417  -6.487       0.000000000126 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.5217 on 1255 degrees of freedom
Multiple R-squared:  0.2323,    Adjusted R-squared:  0.2298 
F-statistic: 94.91 on 4 and 1255 DF,  p-value: < 0.00000000000000022

Putting in the variable looks means that better looks always has to have a positive effect. It is not as significant and fits slightly less well (use adjusted R2 ).

sd(beauty$looks)
[1] 0.6848774

A one standard deviation increase in looks increases predicted lwage by .062(.68) = .042, or predicted wage by about 4.2%.

Let’s see what happens if we look at the effects just for women

summary(lm(lwage ~ belowav+ abovav+educ+stats::poly(exper,2), data=subset(beauty,female ==1)))

Call:
lm(formula = lwage ~ belowav + abovav + educ + stats::poly(exper, 
    2), data = subset(beauty, female == 1))

Residuals:
     Min       1Q   Median       3Q      Max 
-1.31286 -0.30574  0.02896  0.29003  3.01740 

Coefficients:
                        Estimate Std. Error t value             Pr(>|t|)    
(Intercept)             0.313361   0.117387   2.669              0.00788 ** 
belowav                -0.125710   0.068573  -1.833              0.06746 .  
abovav                  0.043335   0.050500   0.858              0.39130    
educ                    0.078645   0.009048   8.692 < 0.0000000000000002 ***
stats::poly(exper, 2)1  2.378840   0.477596   4.981          0.000000918 ***
stats::poly(exper, 2)2 -1.287558   0.477283  -2.698              0.00726 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.468 on 430 degrees of freedom
Multiple R-squared:  0.2126,    Adjusted R-squared:  0.2035 
F-statistic: 23.23 on 5 and 430 DF,  p-value: < 0.00000000000000022

Equation for women only is suggestive of a positive effect of above average looks, but the estimates are imprecise with only 213 observations. In fact, belavg is no longer statistically significant even though its coefficient is still pretty large, −.125.

One shortcoming in the previous analysis is that it ignores occupation. Maybe we should allow people to sort into occupation (perhaps partly based on looks) and see if there is a “looks premium” in a given occupation. Biddle and Hamermesh (1998, Journal of Labor Economics) study lawyers’ looks and earnings and find similar results.

Recently, a paper found that better looking economists are cited more frequently and are more likely to be placed in higher ranking schools.

Variables such as credit ratings, or any variables asked on a scale, are ordered variables. For example, someone may be assigned a credit rating on a scale from 1 to 7, or someone may be asked to rate their “happiness” on a scale of 1 to 5.

Interactions with Dummy Variables

Consider again the lwage equation with gender and marital status, allowing for the four different groups. We can achieve the same thing by using an interaction between female and married.

If we regress lwage on female, married, female * married and the education, experience, and tenure variables, we get:

summary(lm(log(wage) ~ female+married +female*married, data = wage1))

Call:
lm(formula = log(wage) ~ female + married + female * married, 
    data = wage1)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.0240 -0.3245 -0.0800  0.3155  1.6849 

Coefficients:
               Estimate Std. Error t value
(Intercept)     1.52081    0.05099  29.827
female         -0.13164    0.06680  -1.971
married         0.42669    0.06155   6.932
female:married -0.37479    0.08571  -4.373
               Pr(>|t|)    
(Intercept)     < 2e-16 ***
female           0.0493 *  
married        1.23e-11 ***
female:married 1.48e-05 ***
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.4728 on 522 degrees of freedom
Multiple R-squared:  0.2132,    Adjusted R-squared:  0.2087 
F-statistic: 47.15 on 3 and 522 DF,  p-value: < 2.2e-16

Just plug in the correct combination of zeros and ones to obtain differences among the groups. The intercept corresponds to female = 0, married = 0, so it is still for single men. For single women, female = 1, married = 0, and married men married = 1, and for married women female =1, married =1, female*married = 1 (-6.226)

One advantage of the equation with the interaction is that it allows us to read off the difference in marriage premium between women and men. For men, the premium is the coefficient on married, 2.815. The difference in the marriage premium is -2.8607 , and so the marriage premium for women is 2.815 − -2.8607 = -.0457.

We can interact dummy variables with quantitative variables to obtain regression models with different slopes, as well as different intercepts.

Recall that in the model \(lwage = β_0 + δ_0female + β_1exper + u,\) the intercept for men is \(β_0\) and that for women is \(δ_0\). The slope, $_1$1, is common across men and women.

How can we allow the return to experience – that is, the slope in the lwage equation – to differ by gender?

An extended model is $lwage = (β_0 + δ_0female) + (β_1 + δ_1female) · exper +u $

For men, female = 0. For women, plug in female = 1.

Intercept
Male \(\beta_0\) \(\beta_1\)
Female \(\beta_0 + \gamma_0\) \(\beta_1 + \gamma_1\)
Diff(Female-Male) \(\gamma_0\) \(\gamma_1\)

For now, we use the Greek letter delta to emphasize that \(δ_0\) and \(δ_1\) are differences.

How can we estimate the four parameters, \(β_0,β_1,δ_0\), and$ _1$? Write the model as \(lwage = β_0 + δ_0female + β_1exper + δ_1female · exper + u\) so we simply add the interaction term female · exper.

Note that female · exper is zero whenever female = 0 (that is, for all men).

Let’s add experience

summary(lm(log(wage) ~ female + exper+ female*exper, data = wage1))

Call:
lm(formula = log(wage) ~ female + exper + female * exper, data = wage1)

Residuals:
     Min       1Q   Median       3Q 
-2.04133 -0.32424 -0.05026  0.35537 
     Max 
 1.66394 

Coefficients:
              Estimate Std. Error t value
(Intercept)   1.697672   0.048639  34.903
female       -0.293432   0.068596  -4.278
exper         0.006601   0.002198   3.004
female:exper -0.005863   0.003157  -1.857
             Pr(>|t|)    
(Intercept)   < 2e-16 ***
female       2.25e-05 ***
exper          0.0028 ** 
female:exper   0.0638 .  
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.4902 on 522 degrees of freedom
Multiple R-squared:  0.1544,    Adjusted R-squared:  0.1496 
F-statistic: 31.78 on 3 and 522 DF,  p-value: < 2.2e-16

The intercept for men is 1.69 and the slope is 0.004 (about .40%) for each year of experience The intercept for women is 1.69 -.293 (1.397) and the slope is 0.006 -0.0058 (about .0002) for each year of experience. The interaction term is marginally statistically significant with a p-value of .0638

Must use care to interpret the coefficient on female when female·exper is in the equation. To see why, at any level of experience, the predicted difference in lwage between females and males is -.293 + .006exper

Therefore, the coefficient on female, -.293, is the predicted difference in lwage between a woman and man when exper = 0. This is not an especially interesting subset of the population. (Only about 1.5% of the sample has exper less than 3, and no one can have zero years.)

Must use care to interpret the coefficient on female when female·exper is in the equation. To see why, at any level of experience, the predicted difference in lwage between females and males is −.518 + .0234exper

More interesting is the gap at around the mean, say exper = 10:

1.69 - 0.293(10) = −1.34 or about 134% less for women.

The gap never fully closes. The largest amount of experience in the sample is ~14 years.

We can use the same centering scheme as before with interactions. Re- place female · exper with female · (exper − 10) so that the coefficient on femalebecomes the difference at 10 years of experience. where 10 is close to the mean value of experience in the sample.

library(dplyr)
library(tibble)
wage1 <- mutate(wage1, femexp_10 = female*(exper-10))

summary(lm(log(wage) ~ female + exper+ femexp_10, data = wage1))

Call:
lm(formula = log(wage) ~ female + exper + femexp_10, data = wage1)

Residuals:
     Min       1Q   Median       3Q 
-2.04133 -0.32424 -0.05026  0.35537 
     Max 
 1.66394 

Coefficients:
             Estimate Std. Error t value
(Intercept)  1.697672   0.048639  34.903
female      -0.352066   0.048151  -7.312
exper        0.006601   0.002198   3.004
femexp_10   -0.005863   0.003157  -1.857
            Pr(>|t|)    
(Intercept)  < 2e-16 ***
female      9.98e-13 ***
exper         0.0028 ** 
femexp_10     0.0638 .  
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.4902 on 522 degrees of freedom
Multiple R-squared:  0.1544,    Adjusted R-squared:  0.1496 
F-statistic: 31.78 on 3 and 522 DF,  p-value: < 2.2e-16

Don’t mind the numbers here, but let’s visualize what hese interactions look like.

intercept differ Let’s add a variable of college and interact it with gender

wage1 <- mutate(wage1, coll = if_else(educ > 15,1,0))

female_educ <-lm(log(wage) ~ female + exper+ female*exper +coll +female*coll, data = wage1)
summary(female_educ)

Call:
lm(formula = log(wage) ~ female + exper + female * exper + coll + 
    female * coll, data = wage1)

Residuals:
     Min       1Q   Median       3Q 
-1.94947 -0.28663 -0.04912  0.28330 
     Max 
 1.33522 

Coefficients:
              Estimate Std. Error t value
(Intercept)   1.509006   0.050225  30.045
female       -0.202312   0.068747  -2.943
exper         0.010018   0.002054   4.878
coll          0.518431   0.064069   8.092
female:exper -0.007385   0.002934  -2.517
female:coll   0.021385   0.107972   0.198
             Pr(>|t|)    
(Intercept)   < 2e-16 ***
female         0.0034 ** 
exper        1.43e-06 ***
coll         4.18e-15 ***
female:exper   0.0121 *  
female:coll    0.8431    
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.4483 on 520 degrees of freedom
Multiple R-squared:  0.2954,    Adjusted R-squared:  0.2886 
F-statistic:  43.6 on 5 and 520 DF,  p-value: < 2.2e-16

Not all of the interaction are significant, but let’s test to see if there are differences between male and female earnings.

Chow Test

We can use the chow test to test for these differences. Chow tests are known for identifying structural breaks - and they have many uses. But, really, it’s just testing of equality between groups.

Take the regression equation: \(lwage = β_0 + δ_0female + β_1exper + δ_1female · exper +β_2coll + δ_2female · coll + u\)

The null hypothesis that there is no difference in lwage between men and women at the same levels of experience and college is:

\(H_0 :δ_0 =0,δ_1 =0,δ_2 =0\)

This is one version of the Chow test - which tests for the equality of regression functions across two groups. We test joint significance of the dummy variable defining the groups as well as the interaction terms.

In the general \(k\) variable case, we can define a dummy variable, \(w\), indicating the two groups. Then

\[\begin{equation}y =\beta _{0} +\beta _{1} x_{1} +\beta _{2} x_{2} +\ldots +\beta _{k} x_{k} \\ +\delta _{0} w +\delta _{1} w \cdot x_{1} +\delta _{2} w \cdot x_{2} +\ldots +\delta _{k} w \cdot x_{k} +u \\ H_{0} :\delta _{0} =0 ,\delta _{1} =0 ,\delta _{2} =0 ,\ldots ,\delta _{k} =0\end{equation}\]for \(k +1\) restrictions.

We can use a standard \(F\) test of the \(k +1\) exclusion restrictions.

It is often of interest to allow \(\delta _{0} \neq 0\) and just test equality of the slopes:

\[\begin{equation*}H_{0} :\delta _{1} =0 ,\delta _{2} =0 ,\ldots ,\delta _{k} =0 \end{equation*}\]Now we are testing \(k\) parameters under \(H_{0}\), so we use the \(\mathcal{F}_{k ,n -2 (k +1)}\) distribution.

We can use the sum of squared residuals version of the \(F\) statistic, too. Rather than construct all of the interactions and run the regressions with and without the interactions, we can compute three SSRs.

  1. Pool the data and estimate a single regression. This is the restricted model, and produces the restricted SSR. Call this the SSR, \(S S R_{P}\).

  2. Estimate the regressions on the two groups (say, 1 and 2) separately. Get the SSRs, \(S S R_{1}\) and \(S S R_{2}\). The unrestricted SSR is \(S S R_{1} +S S R_{2}\) (and this is the same as the regression that includes the full set of interactions).

The \(F\) statistic is \[\begin{equation*}F =\frac{[S S R_{P} -( S S R_{1} +S S R_{2})]/(k +1)}{(S S R_{1} +S S R_{2})/[n -2(k +1)]} \end{equation*}\]and, under \(H_{0}\), has the \(\mathcal{F}_{k +1 ,n -2 (k _1)}\) distribution under \(H_{0}\).

If we leave the intercepts unrestricted under \(H_{0}\), then \(S S R_{P}\) is obtained from the pooled regression but with the dummy variable added. The \(k +1\) in the numerator becomes \(k\), and we use the \(\mathcal{F}_{k +1 ,n -2 (k_1)}\) distribution.

library(stargazer)
library(car)

# create a regression for our full sample, male and female samples
wage_full <-lm(log(wage) ~ exper+ coll , data = wage1)

#calculate the sum of square residual
ssp <- sum(resid(wage_full)^2)

wage_fem <-lm(log(wage) ~ exper+ coll , data = subset(wage1, female ==1))
ss2 = sum(resid(wage_fem)^2)

wage_m <-lm(log(wage) ~ exper+ coll , data = subset(wage1, female ==0))
ss1 = sum(resid(wage_m)^2)

#Now, we can calculate our Chow test
chowtest <- (ssp - (ss1+ss2) /4) / ((ss1+ss2)/(526-2*(4)))
chowtest

[1] 461.8706

# now add the intercept shift (recall that's what a dummy variable is, just an intercept shift, not a intercept AND slope shift which is what an interaction between a dummy variable and continuous variable is)

summary(wage_f_int <-lm(log(wage) ~ stats::poly(exper,2)+ coll +female , data = wage1))

Call: lm(formula = log(wage) ~ stats::poly(exper, 2) + coll + female, data = wage1)

Residuals: Min 1Q Median 3Q Max -1.7834 -0.2977 -0.0075 0.2681 1.3395

Coefficients: Estimate Std. Error (Intercept) 1.67805 0.02853 stats::poly(exper, 2)1 1.97958 0.43342 stats::poly(exper, 2)2 -3.36549 0.42664 coll 0.50730 0.04896 female -0.31364 0.03779 t value Pr(>|t|) (Intercept) 58.816 < 2e-16 stats::poly(exper, 2)1 4.567 6.17e-06 stats::poly(exper, 2)2 -7.888 1.81e-14 coll 10.362 < 2e-16 female -8.299 9.07e-16

(Intercept) stats::poly(exper, 2)1 stats::poly(exper, 2)2 coll female *** — Signif. codes:
0 ‘’ 0.001 ‘’ 0.01 ‘’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.426 on 521 degrees of freedom Multiple R-squared: 0.3624, Adjusted R-squared: 0.3575 F-statistic: 74.04 on 4 and 521 DF, p-value: < 2.2e-16

stargazer(wage_full, wage_fem, wage_m, wage_f_int, type = "html", 
          results = 'asis',message = FALSE, echo = FALSE, notes.append = FALSE, header = FALSE, single.row = TRUE)
the condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changednumber of rows of result is not a multiple of vector length (arg 2)
Dependent variable:
log(wage)
(1) (2) (3) (4)
exper 0.007*** (0.002) 0.003 (0.002) 0.010*** (0.002)
stats::poly(exper, 2)1 1.980*** (0.433)
stats::poly(exper, 2)2 -3.365*** (0.427)
coll 0.590*** (0.054) 0.540*** (0.079) 0.518*** (0.069) 0.507*** (0.049)
female -0.314*** (0.038)
Constant 1.389*** (0.037) 1.307*** (0.043) 1.509*** (0.054) 1.678*** (0.029)
Observations 526 252 274 526
R2 0.196 0.157 0.196 0.362
Adjusted R2 0.193 0.150 0.190 0.358
Residual Std. Error 0.478 (df = 523) 0.409 (df = 249) 0.481 (df = 271) 0.426 (df = 521)
F Statistic 63.594*** (df = 2; 523) 23.197*** (df = 2; 249) 33.094*** (df = 2; 271) 74.042*** (df = 4; 521)
Note: p<0.1; p<0.05; p<0.01
asis
FALSE
FALSE

An advantage of the approach based on interactions, that we will see when discussing heteroskedasticity, is that it can be modified to allow for unknown heteroskedasticity. (The statistic we use here assumes Assumption MLR.5, homoskedasticity, but we can relax that.) The SSR approach intrinsically relies on Assumption MLR.5.

We can see the different interactions visually (an example with randomly generated data)

# generate artificial data
set.seed(1)

X <- runif(200,0, 15)
D <- sample(0:1, 200, replace = T)
Y <- 450 +  150 * X + 500 * D + 50 * (X * D) + rnorm(200, sd = 300)

# estimate the models and plot the regression lines

# 1. (baseline model)
plot(X, log(Y),
     pch = 20,
     col = "steelblue",
     main = "Different Intercepts, Same Slope")

mod1_coef <- lm(log(Y) ~ X + D)$coefficients

abline(coef = c(mod1_coef[1], mod1_coef[2]), 
       col = "red",
       lwd = 1.5)

abline(coef = c(mod1_coef[1] + mod1_coef[3], mod1_coef[2]), 
       col = "green",
       lwd = 1.5)

       
# 2. (baseline model + interaction term)
plot(X, log(Y),
     pch = 20,
     col = "steelblue",
     main = "Different Intercepts, Different Slopes")

mod2_coef <- lm(log(Y) ~ X + D + X:D)$coefficients

abline(coef = c(mod2_coef[1], mod2_coef[2]), 
       col = "red",
       lwd = 1.5)

abline(coef = c(mod2_coef[1] + mod2_coef[3], mod2_coef[2] + mod2_coef[4]), 
       col = "green",
       lwd = 1.5)


# 3. (omission of D as regressor + interaction term)
plot(X, log(Y),
     pch = 20,
     col = "steelblue",
     main = "Same Intercept, Different Slopes")

mod3_coef <- lm(log(Y) ~ X + X:D)$coefficients

abline(coef = c(mod3_coef[1], mod3_coef[2]), 
       col = "red",
       lwd = 1.5)

abline(coef = c(mod3_coef[1], mod3_coef[2] + mod3_coef[3]), 
       col = "green",
       lwd = 1.5)

A final warning: it is hard to justify omitting the level of a variable but including an interaction that involves that variable. Suppose we drop coll but include female · coll.

The model imposes a zero return to college for men – which we cannot justify – and the coefficient on femcoll is now a direct estimate of the return to college for women, rather than being the difference in the returns between women and men

Linear Probability Model

What if the dependent variable is a dummy variable?

How do we interpret the population model:

\[\begin{equation}y =\beta _{0} +\beta _{1} x_{1} +\beta _{2} x_{2} +\ldots +\beta _{k} x_{k} +u \end{equation}\]when \(y\) is binary? \(y\) can only change from 0 to 1 or 1 to zero. Suppose \(\beta _{1} =.035\) and \(x_{1} =educ\). What does it mean for a one year increased in \(educ\) to increase \(y\) by \(.035\text{?}\)

Same problem arises for other discrete variables, such as \(y =number\) \(of\) \(arrests\) or \(y =number\) \(of\) \(children\). Cannot have a fraction more of a child.

The key relationship when \(y\) is binary:

\[\begin{equation*}E (y\vert \mathbf{x}) =P (y =1\vert \mathbf{x}) \end{equation*}\]

We call \(P (y =1\vert \mathbf{x})\) the . Thus, wen we apply the linear model to binary \(y\) we are really saying

\[\begin{equation*}P (y =1\vert \mathbf{x}) =\beta _{0} +\beta _{1} x_{1} +\beta _{2} x_{2} +\ldots +\beta _{k} x_{k} \end{equation*}\]and we call the model the .

The important point is that all partial effects are effects on the probability that \(y =1\) (sometimes called a ``success’’). Since \(P (y =0\vert \mathbf{x}) =1 -P (y =1\vert \mathbf{x})\) it is the only probability we need.

\[\begin{equation*} \Delta P (y =1\vert \mathbf{x}) =\beta _{j} \Delta x_{j}\text{holding other explanatory variables fixed} \end{equation*}\]

The sample analog holds as well. When we have the OLS regression line

\[\begin{equation*}\hat{y} =\hat{\beta }_{0} +\hat{\beta }_{1} x_{1} +\hat{\beta }_{2} x_{2} +\ldots +\hat{\beta }_{k} x_{k}\text{,} \end{equation*}\] \(\hat{y}\) is now the predicted probability.

The intercept is the predicted probability when each \(x_{j}\) is set to zero (which, as with other regression applications, may not make sense).

\(\hat{\beta }_{j}\) measures the change in the estimated probability of a ``success’’ when $ x_{j} =1$, other factors held fixed.

Just like in any regression application, we can have explanatory variables in logs, quadratics, and interactions as well as binary regressors.

Let’s take the following example: The variable inlf is one if a woman worked for a wage during a certain year, and zero if not. We estimate a linear probability model to see the effects of variables on the probability of being in the labor force.

library(wooldridge)
data("mroz")

summary(lm(inlf~nwifeinc+educ+exper+expersq+age+kidslt6+kidsge6, data = mroz))

Call:
lm(formula = inlf ~ nwifeinc + educ + exper + expersq + age + 
    kidslt6 + kidsge6, data = mroz)

Residuals:
     Min       1Q   Median       3Q 
-0.93432 -0.37526  0.08833  0.34404 
     Max 
 0.99417 

Coefficients:
              Estimate Std. Error t value
(Intercept)  0.5855192  0.1541780   3.798
nwifeinc    -0.0034052  0.0014485  -2.351
educ         0.0379953  0.0073760   5.151
exper        0.0394924  0.0056727   6.962
expersq     -0.0005963  0.0001848  -3.227
age         -0.0160908  0.0024847  -6.476
kidslt6     -0.2618105  0.0335058  -7.814
kidsge6      0.0130122  0.0131960   0.986
            Pr(>|t|)    
(Intercept) 0.000158 ***
nwifeinc    0.018991 *  
educ        3.32e-07 ***
exper       7.38e-12 ***
expersq     0.001306 ** 
age         1.71e-10 ***
kidslt6     1.89e-14 ***
kidsge6     0.324415    
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.4271 on 745 degrees of freedom
Multiple R-squared:  0.2642,    Adjusted R-squared:  0.2573 
F-statistic: 38.22 on 7 and 745 DF,  p-value: < 2.2e-16

These are the usual OLS t statistics, even though we will show they are not quite valid.

The intercept is not of interest here. The coefficient on nwifeinc (other sources of income) shows a modest effect: if it increases by 20 ($20, 000, about one standard deviation), the probability of being in the labor force falls by .068, or 6.8 percentage points. The t statistic shows it is statistically significant at the 2% level.

Each year of education increases the probability by an estimated .038, or 3.8 percentage points.

Using a linear model for a binary outcome is convenient because estimation is easy and so is interpretation.

Past workforce experience has a positive but diminishing effect. The effect of the first year is about .039, and this diminishes to zero at exper = .039/(2 · .0006) = 32.5. (Only 13 women have experience > 32.)

Having young children has a very large negative effect: being in the labor force falls by .262 for each young child. Almost all of the action is between 0 and 1, with a little from 1 to 2.

It is unwise to extrapolate to extreme values when using any linear model, including this one (values can go above 1

But the LPM does have some shortcomings:

  1. The fitted values from an OLS regression are never guaranteed to be between zero and one, yet these fitted values are estimated probabilities.
  1. The estimated partial effects are constant throughout the range of the explanatory variables, possibly leading to silly estimated effects for large changes. (This is related to predicted probabilities possibly being negative or greater than one.)

For example, take a woman who has no other source of income, 25 years of prior work experience, no children, who is 48 years old. As a function of \(e d u c\) the equation looks like

\[\begin{equation*}\widehat{i n l f} =.417 +.038\text{}e d u c \end{equation*}\]

At \(e d u c =12\), the predicted probability is \(.873\), at \(e d u c =14\) it is \(.949\), and at \(e d u c =16\), \(\widehat{i n l f} =1.025\). For the estimated model to truly represent a probability, the effect of education should be diminishing – that is, the next year of education should increase the probability by less than the previous year so that the estimated probability never goes above one.

Using logarithms does not bound the effect, and using quadratics often does not help. (In this example, a quadratic in \(e d u c\) gives an estimated effect, not a diminishing effect.) with this problem.

But the LPM does a good job of approximating partial effects if we do not look at extreme values of the explanatory variables.

Because \(y\) is binary – and this really has nothing to do with the LPM per se – the LPM must exhibit heteroskedasticity except in the one case where no \(x_{j}\) affects \(P (y =1\vert \mathbf{x})\). This follows because for a binary variable,

\[\begin{equation*}V a r (y\vert \mathbf{x}) =p (\mathbf{x})[1 -p(\mathbf{x})] \end{equation*}\]where \(p (\mathbf{x}) =\beta _{0} +\beta _{1} x_{1} +\beta _{2} x_{2} +\ldots +\beta _{k} x_{k}\) is the linear response probability.

This is a case where we MLR.5 must fail, and we know how. So, currently, we treat the usual \(t\) and \(F\) tests with suspicion, and the confidence intervals. (Turns out they are often pretty reliable in LPMs.)

Some tweets from the author about LPM (APE = Average Partial Effects): lpm

lpm2

Another thing to note is that our usual \(R^2\) doesn’t measure fit as well. Instead, it’s easier to think of prediction in terms of “success” and “failures”. Is the model better at predicting successes, failures, or is overall, doing a good job predicting both?

The fraction correctly predicted is one way to think about fit in LPM: \[\bar{y} \times \text{Pr}(\hat{Y}=1|Y=1) + (1-\bar{y}) \times \text{Pr}(\hat{Y}=0|Y=0)\] where \(\bar{y}= N^{-1}\sum_i^N Y_i\). What is \((1-\bar{y})\)?

We need a classification rule, usually (but not necessarily)

$ _i = 1 _i 0.5 $ and \(\tilde{y}_i = 0 ~~\text{if}~~ \hat{p}_i < 0.5\)

This classification rule is up to you as the researcher - what’s the cutoff rule that the probability of X be counted as a “success”.

Then, we can do all sorts of classifications:

Residual Analysis

Sometimes we want to know how particular units actually fair compared with their predicted outcome based on the explanatory variables we observe.

Consider predicting school performance. Given demographic information on the students and resources used, is a school doing better or worse than predicted?

It is known that students from disadvantage backgrounds do worse, and some evidence school inputs also affect outcomes.

So do not just look at raw scores, but adjust them for observable features. The residual can be viewed as an estimate of the “value added.”

\[\begin{gather*}\hat{u}_{i} =y_{i} -\hat{y}_{i} \\ \hat{u}_{i} >0 \Longrightarrow y_{i} >\hat{y}_{i} \\ \hat{u}_{i} <0 \Longrightarrow y_{i} <\hat{y}_{i}\end{gather*}\]

Caveats:

  1. The residuals have to average to zero, so there will be some positive and negative residuals no matter what.

  2. The residual depends on the estimates, \(\hat{β_j}\).

  3. Even if we know the \(β_j, u_i\) is just a single draw.

  4. We may be missing important predictors of y that are then in the error term.

data(meap00_01)
school <- lm(math4 ~ lunch +lenroll+ lexppp, data=meap00_01)
summary(school)

Call:
lm(formula = math4 ~ lunch + lenroll + lexppp, data = meap00_01)

Residuals:
    Min      1Q  Median      3Q     Max 
-56.326  -8.758   0.914   9.164  51.416 

Coefficients:
            Estimate Std. Error t value
(Intercept) 91.93246   19.96170   4.605
lunch       -0.44874    0.01464 -30.648
lenroll     -5.39915    0.94041  -5.741
lexppp       3.52474    2.09785   1.680
            Pr(>|t|)    
(Intercept) 4.42e-06 ***
lunch        < 2e-16 ***
lenroll     1.11e-08 ***
lexppp        0.0931 .  
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 15.3 on 1688 degrees of freedom
Multiple R-squared:  0.3729,    Adjusted R-squared:  0.3718 
F-statistic: 334.6 on 3 and 1688 DF,  p-value: < 2.2e-16
predict_school<- tibble(predict(school))

The predicted values vary much less than the actual outcomes (the fairly low R-squared, .372, implies this).

Consider schools 3 and 4. Their predicted outcomes (based on lunch, lenroll, lexppp) are close, about 80.95 and 77.16, respectively. But the actual outcome for school 4, 85.2, is 10 points higher than school 3, 77.3.

With only a few explanatory variables, residual analysis can be misleading. We may be missing important factors that, if controlled for, could dramatically change the rankings.

We can also observe our residuals and do a visual inspection of residuals - remembering the caveats.

In the first graph, we can see the residuals versus the fitted. This graph, as we talked about before, shows the presence of heteroskedasticity. (Remember that the average of our residuals should be 0, so that red line shows just that - it’s approximately 0). We suspect heteroskedasticity because of the “funnel” shape. The scale-location graph similarly shows this pattern (we’d be shocked otherwise, after all the SER is the average mistake we make in our regression and is a measure of fit)

This is useful to look at to inspect issues with time-series.


plot(school)

NA

We can also analyze the residual distribution. It should be close to a normal distribution given our assumptions.

u<-meap00_01$math4 - predict_school$'predict(school)'

predict_school
d <- density(u)
plot(d)
polygon(d, col="red", border="blue")

LS0tCnRpdGxlOiAiSW50ZXJwcmV0YXRpb24gb2YgUmVncmVzc2lvbnMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KIyMgTm90ZSBvbiBVbml0cyBvZiBtZWFzdXJlbWVudApXZSBrbm93IGZyb20gc2ltcGxlIHJlZ3Jlc3Npb24gdGhhdCBjaGFuZ2UgdGhlIHVuaXRzIG9mIG1lYXN1cmVtZW50IG9mIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgb3Igc29tZSBvZiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzIGNhbm5vdCBjaGFuZ2UgdGhlIGludGVycHJldGF0aW9uIG9mIHRoZSBPTFMgcmVncmVzc2lvbiBsaW5lLgoKVGhpcyBtZWFucyB0aGF0IGlmIHdlIHJlc2NhbGUgYW55IG9mIG91ciB2YXJpYWJsZXMsIHRoZSBjb2VmZmljaWVudHMgaGF2ZSB0byBjaGFuZ2UgdG8ga2VlcCB0aGUgaW50ZXJwcmV0YXRpb24gdW5jaGFuZ2VkLgoKMS4gSWYgd2UgbXVsdGlwbHkgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSB5IGJ5IGEgbm9uemVybyBjb25zdGFudCwgc2F5IGMsIGFsbCBvZiB0aGUgY29lZmZpY2llbnRzIOKAkyB0aGUgaW50ZXJjZXB0IGFuZCB0aGUgc2xvcGVzIOKAkyBnZXQgbXVsdGlwbGllZCBieSBjLiBTbyBkbyB0aGUgZml0dGVkIHZhbHVlcyBhbmQgcmVzaWR1YWxzLiBOb3RoaW5nIGhhcHBlbnMgdG8gdGhlIFItc3F1YXJlZC4gTm90aGluZyBoYXBwZW5zIHRvIHQgc3RhdGlzdGljcyAoZXhjZXB0IHRoZXkgY2hhbmdlIHNpZ24gaWYgYyA8IDApIG9yIEYgc3RhdGlzdGljcy4KCjIuIElmIHdlIG11bHRpcGx5IGFuIGluZGVwZW5kZW50IHZhcmlhYmxlICR4X2okIGJ5IHRoZSBub256ZXJvIGNvbnN0YW50IGMgdGhlbiB0aGUgY29lZmZpY2llbnQgaW4gJHhfaiQgZ2V0cyBkaXZpZGVkIGJ5IGMuIE5vdGhpbmcgaGFwcGVucyB0byBmaXR0ZWQgdmFsdWVzLCByZXNpZHVhbHMsIG9yIFItc3F1YXJlZC4gTm90aGluZyBoYXBwZW5zIHRvIHQgb3IgRiBzdGF0aXN0aWNzLCBleGNlcHQgdGhlIHQgc3RhdGlzdGljIG9uIHRoZSBuZXcgJHhfaiQgdmFyaWFibGUgY2hhbmdlcyBzaWduIGlmIGMgPCAwLgoKMy4gU3VwcG9zZSB5ID4gMCBhbmQgd2UgaW5pdGlhbGx5IHVzZSBsb2coeSkgYXMgdGhlIGRlcGVuZGVudCB2YXJpYWJsZS4gSWYgd2UgZmlyc3QgbXVsdGlwbHkgeSBieSB0aGUgY29uc3RhbnQgYyA+IDAgYW5kIHRoZW4gdGFrZSB0aGUgbG9nLCBvbmx5IHRoZSBpbnRlcmNlcHQgaW4gdGhlIHJlZ3Jlc3Npb24gd2lsbCBjaGFuZ2UuIFRoaXMgaXMgYmVjYXVzZSBsb2coYyDCtyB5KSA9IGxvZyhjKSArIGxvZyh5KS4gQXMgYW4gZXhhbXBsZSwgc3VwcG9zZSB5IGlzIGluaXRpYWxseSBpbiB0aG91c2FuZHMgb2YgZG9sbGFycy4gVGhlbiAxLCAwMDAgwrcgeSBpcyBpbiBkb2xsYXJzLiBOb3cgbG9nKDEsIDAwMCDCtyB5KSA9IGxvZygxLCAwMDApICsgbG9nKHkpIOKJiCA2LjkxLAphbmQgc28gdGhlIGludGVyY2VwdCB3aWxsIGluY3JlYXNlIGJ5IGFib3V0IDYuOTEuIE5vbmUgb2YgdGhlIHNsb3BlcyBjaGFuZ2VzLiBUaGUgZml0dGVkIHZhbHVlcyBlYWNoIGluY3JlYXNlcyBieSA2LjkxLCBidXQgdGhlIHJlc2lkdWFscyBhbmQgUi1zcXVhcmVkIGRvIG5vdCBjaGFuZ2UuIE5vdGhpbmcgaGFwcGVucyB0byB0IG9yIEYgc3RhdGlzdGljcy4KCjQuIElmIHdlIHVzZSAkbG9nKGMgwrcgeF9qKSQgaW5zdGVhZCBvZiAkbG9nKHhfaikkLCB0aGUgaW50ZXJjZXB0IGNoYW5nZXMgYnV0IHRoZSBjb2VmZmljaWVudCBvbiAkeF9qJCBkb2VzIG5vdDsgbmVpdGhlciBkb2VzIHRoZSBSLXNxdWFyZWQgb3IgYW55IHRlc3Qgc3RhdGlzdGljcyAoZXhjZXB0IGZvciB0aG9zZSByZWxhdGluZyB0byB0aGUgaW50ZXJjZXB0KS4KCiMjIFVzaW5nIGEgTmF0dXJhbCBMb2cKCiMjIyBSZWFzb25zIGZvciBVc2luZyB0aGUgTmF0dXJhbCBMb2cKCjEuIFRoZSBjb2VmZmljaWVudHMgaGF2ZSBwZXJjZW50YWdlIGNoYW5nZSBpbnRlcnByZXRhdGlvbnMuIENvbnNlcXVlbnRseSwgd2UgY2FuIGJlIGlnbm9yYW50IG9mIHRoZSB1bml0cyBvZiBtZWFzdXJlbWVudCBvZiBhbnkgdmFyaWFibGUgdGhhdCBhcHBlYXJzIGluIGxvZ2FyaXRobWljIGZvcm0uCgoyLiBXaGVuIHkgPiAwLCBtb2RlbHMgd2l0aCBsb2coeSkgYXMgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBvZnRlbiBtb3JlIGNsb3NlbHkgc2F0aXNmeSB0aGUgY2xhc3NpY2FsIGxpbmVhciBtb2RlbCBhc3N1bXB0aW9ucy4gRm9yIGV4YW1wbGUsIHRoZSBtb2RlbCBoYXMgYSBiZXR0ZXIgY2hhbmNlIG9mIGJlaW5nIGxpbmVhciwgaG9tb3NrZWRhc3RpY2l0eSBpcyBtb3JlIGxpa2VseSB0byBob2xkLCBhbmQgbm9ybWFsaXR5IGlzIG9mdGVuIG11Y2ggbW9yZSBwbGF1c2libGUuIChUaGVzZSBhcmUgb2JzZXJ2YXRpb25zIGJhc2VkIG9uIGV4cGVyaWVuY2UuKQoKMy4gSW4gbW9zdCBjYXNlcywgdGFraW5nIHRoZSBsb2cgZ3JlYXRseSByZWR1Y2VzIHRoZSB2YXJpYW5jZSBvZiBhIHZhcmlhYmxlLCBtYWtpbmcgT0xTIGVzdGltYXRlcyBsZXNzIHByb25lIHRvIG91dGxpZXIgaW5mbHVlbmNlLiAKCiMjIyMgTGltaXRhdGlvbnMgb2YgVXNpbmcgdGhlIE5hdHVyYWwgTG9nCgoxLiBJZiB5IOKJpSAwIGJ1dCB5ID0gMCBpcyBwb3NzaWJsZSwgd2UgY2Fubm90IHVzZSBsb2coeSkuIFNvbWV0aW1lcyBsb2coMSArIHkpIGlzIHVzZWQsIGJ1dCBpbnRlcnByZXRhdGlvbiBvZiB0aGUgY29lZmZpY2llbnRzIGlzIGRpZmZpY3VsdCwgYW5kIGxvZygxICsgeSkg4omlIDAgaWYgeSDiiaUgMC4KCjIuIEl0IGlzIGhhcmRlciB0byBwcmVkaWN0IHkgd2hlbiB3ZSBoYXZlIGVzdGltYXRlZCBhIG1vZGVsIGZvciBsb2coeSkuIAoKMy4gSW4gY2FzZXMgd2hlcmUgeSBpcyBhIGZyYWN0aW9uIGFuZCBjbG9zZSB0byB6ZXJvIGZvciBtYW55IG9ic2VydmF0aW9ucywgbG9nKCR5X2kkKSBjYW4gaGF2ZSBtb3JlIHZhcmlhYmlsaXR5IHRoYW4gJHlfaSQuCgpDb25zaWRlciB1bmVtLCB0aGUgdW5lbXBsb3ltZW50IHJhdGUuIEJlY2F1c2UgdW5lbXBsb3ltZW50IGlzIGEgcGVyY2VudCwgY2hhbmdlcyBhcmUgcGVyY2VudGFnZSBwb2ludCBjaGFuZ2VzLiBTbywgdW5lbSBnb2luZyBmcm9tIDggdG8gOSBpcyBhIG9uZSBwZXJjZW50YWdlIHBvaW50IGluY3JlYXNlLCBidXQgaXQgaXMgYSAxMi41IHBlcmNlbnQgaW5jcmVhc2UgZnJvbSB0aGUgc3RhcnRpbmcgdmFsdWUgb2YgOC4gVGhlIGxvZ2FyaXRobWljIGNoYW5nZSBpcyBsb2coOSkg4oiSIGxvZyg4KSDiiYggLjExOCwgd2hpY2ggbWVhbnMgYXBwcm94aW1hdGVseSAxMS44JSBhcyB0aGUgYXBwcm94aW1hdGlvbiB0byAxMi41JS4gVXN1YWxseSB3ZSBhcmUgbW9yZSBpbnRlcmVzdGVkIGluIHRoZSBlZmZlY3Qgb2YgYSBvbmUgcGVyY2VudGFnZSBwb2ludCBjaGFuZ2UsIGJ1dCBub3QgYWx3YXlzLgoKIyMjIyBTb21lIChOb3Qtc28tSGFyZCkgUnVsZXMgb24gVXNpbmcgTG9nYXJpdGhtcwoKMS4gTG9ncyBhcmUgb2Z0ZW4gdXNlZCBmb3IgZG9sbGFyIGFtb3VudHMgdGhhdCBhcmUgYWx3YXlzIHBvc2l0aXZlLCBhcyB3ZWxsIGFzIGZvciB2YXJpYWJsZXMgc3VjaCBhcyBwb3B1bGF0aW9uLCBlc3BlY2lhbGx5IHdoZW4gdGhlcmUgaXMgYSBsb3Qgb2YgdmFyaWF0aW9uLgoKMi4gTG9ncyBhcmUgdXNlZCBsZXNzIG9mdGVuIGZvciB2YXJpYWJsZXMgbWVhc3VyZWQgaW4geWVhcnMsIHN1Y2ggYXMgc2Nob29saW5nLCBhZ2UsIGFuZCBleHBlcmllbmNlLiBXZSBvZnRlbiB3YW50IHRvIGtub3cgd2hhdCB0aGUgZWZmZWN0IG9mIGluY3JlYXNpbmcgc2Nob29saW5nIGJ5IG9uZSB5ZWFyIChub3QgYnkgYSBjZXJ0YWluIHBlcmNlbnRhZ2UpLgoKMy4gTG9ncyBhcmUgdXNlZCBsZXNzIGluZnJlcXVlbnRseSBmb3IgdmFyaWFibGVzIHRoYXQgYXJlIGFscmVhZHkgcGVyY2VudHMgb3IgcHJvcG9ydGlvbnMuCgojIyMgbG9nLWxpbgogV2UgY2FuIGFwcHJveGltYXRlIHBlcmNlbnRhZ2UgY2hhbmdlcyB1c2luZyB0aGUgbmF0dXJhbCBsb2cgCgpOb3cgbGV0IHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgYmUgJFxsb2coYndnaHQpJDogCgpcYmVnaW57ZXF1YXRpb259Clxsb2coYndnaHQpID1cYmV0YV97MH0gK1xiZXRhX3sxfWZhbWluYyArdQpcZW5ke2VxdWF0aW9ufQoKSG9sZGluZyAkdSQgZml4ZWQsIAoKXGJlZ2lue2VxdWF0aW9ufSAKXERlbHRhIFxsb2coYndnaHQpID1cYmV0YSBfezF9ICBcRGVsdGEgZmFtaW5jClxlbmR7ZXF1YXRpb259CgoKc28sIApcYmVnaW57ZXF1YXRpb259XGJldGFfezF9ID1cZnJhY3sgXERlbHRhIFxsb2cgKGJ3Z2h0KX17IFxEZWx0YSBmYW1pbmN9ClxlbmR7ZXF1YXRpb259CgogVXNlZnVsIHJlc3VsdCBmcm9tIGNhbGN1bHVzOiAKClxiZWdpbntlcXVhdGlvbn0xMDAgXGNkb3QgIFxEZWx0YSBcbG9nKGJ3Z2h0KSAgXGFwcHJveCAgXCUgIFxEZWx0YSBmYW1pbmMKXGVuZHtlcXVhdGlvbn0KClRoaXMgbWVhbnMgd2hlbiAkXGxvZyhid2dodCkgPVxiZXRhIF97MH0gK1xiZXRhIF97MX1mYW1pbmMgK3UkLCB3ZSBoYXZlIGEgc2ltcGxlIGludGVycHJldGF0aW9uIG9mICRcYmV0YV97MX0kOiAKCiQxMDAgXGJldGEgX3sxfSAgXGFwcHJveCAgXCUgIFxEZWx0YSB3YWdlJCB3aGVuICRcRGVsdGEgZmFtaW5jID0xJAoKCldoeSwgeW91IGFzaywgaXMgdGhpcyAkMTAwXHRpbWVzXGJldGFfMSQ/IFdlbGwsICp0ZWNobmljYWxseSogaXQncyBub3QgYWN0dWFsbHkgMTAwJS4gSXQncyBhIHJ1bGUgb2YgdGh1bWIgd2UgdXNlLiBXZSB0cmVhdCBsb2dzIGFzIGFuIGFwcHJveGltYXRlIHBlcmNlbnQgY2hhbmdlLiAKSWYgd2Ugc2V0ICRcZGVsdGEgPSAxJCBmb3IgYSB1bml0IGNoYW5nZToKClxiZWdpbntlcXVhdGlvbn1FW2xuWV8wXSA9IFxiZXRhXzAgK1xiZXRhXzEgWFxlbmR7ZXF1YXRpb259ClxiZWdpbntlcXVhdGlvbn1FW2xuWV8xXSA9IFxiZXRhXzAgK1xiZXRhXzEoWCsxKVxlbmR7ZXF1YXRpb259ClxiZWdpbntlcXVhdGlvbn1FW2xuWV8xXS1FW2xuWV8wXSA9IFxiZXRhXzEoWCsxKSAtXGJldGFfMVhcZW5ke2VxdWF0aW9ufQpcYmVnaW57ZXF1YXRpb259RVtsbllfMV0tRVtsbllfMF0gPSBcYmV0YV8xXGVuZHtlcXVhdGlvbn0KCldoZW4geW91IG11bHRpcGx5ICRcYmV0YV8xJCBieSAxMDAsIHRoZSBhcHByb3hpbWF0aW9uIGlzICRFW2xuWV8xXS1FW2xuWV8wXSBcYXBwcm94IFxmcmFje0VbWV8xXS1FW1lfMF19e0VbWV8wXX0kLiAKCkZvciBzaW1wbGljaXR5LCBsZXQncyBqdXN0IGRyb3AgdGhlIGV4cGVjdGF0aW9ucyBhbmQgdHJlYXQgaXQgYXMgaWYgdGhlcmUgaXMgbm8gdmFyaWFuY2UgaW4gJFlfMCQgYW5kICRZXzEkLiBVc2luZyBsb2ctcnVsZXMsICRsbllfMC1sbllfMSA9IGxuKFxmcmFje1lfMX17WV8wfSkgPSBsbihcZnJhY3tZXzB9e1lfMH0gKyBcZnJhY3tZXzEtWV8wfXtZXzB9KSA9IGxuKDErXGZyYWN7XERlbHRhIFl9e1lfMH0pJCBUaGlzIGxhc3QgcGFydCwgJFxmcmFje1xEZWx0YSBZfXtZXzB9KSQgaXMgbm90aGluZyBlbHNlIGJ1dCB0aGUgcGVyY2VudCBjaGFuZ2UgaW4gWSBkaXZpZGVkIGJ5IDEwMC4KClNvLCB3ZSBnZXQgICAgClxiZWdpbntlcXVhdGlvbn0KbG4oMStcZnJhY3tcRGVsdGF9e1lfMX0pPVxiZXRhClxlbmR7ZXF1YXRpb259CgpXZSBjYW4gZXhwb25lbnRpYXRlIGJvdGggc2lkZXMgYW5kIHNlZSB0aGUgYXBwcm94aW1hdGlvbjoKJFxmcmFje1xEZWx0YSB5fXt5XzF9ID0gZV5cYmV0YS0xIFxhcHByb3ggXGJldGEkIAoKVGhpcyBhcHByb3hpbWF0aW9uIGNvbWVzIGZyb20gYSBrLXRoIG9yZGVyIFRheWxvciBzZXJpZXMgZXhwYW5zaW9uIG9mICRlXlxiZXRhJCBhcm91bmQgemVybyAodGVjaG5pY2FsbHksIE1hY2xhdXJpbiBzZXJpZXMpOgoKXGJlZ2lue2VxdWF0aW9ufQplXlxiZXRhIFxhcHByb3ggUF9rID0gMSArIFxiZXRhKyBcZnJhY3tcYmV0YV4yfXsyIX0rIFxmcmFje1xiZXRhXjN9ezMhfSsgXGRvdHMKXGVuZHtlcXVhdGlvbn0KCldlIG9ubHkgdXNlIHRoZSBsaW5lYXIgYXBwcm94aW1hdGlvbiAoYW5kIGRpc3JlZ2FyZCB0aGUgdGVybXMgZnJvbSB0aGUgcXVhZHJhdGljIG9ud2FyZCksIGl0IHdpbGwgYmUgbW9yZSBhY2N1cmF0ZSB0aGUgc21hbGxlciAkXGJldGEkIGlzLiBUaGlzIGlzIGZpbmUgZm9yIHNtYWxsIGNoYW5nZXMsIGJ1dCB5b3UgbWF5IHdhbnQgdG8gcmVwb3J0ICQxMDAqKGVeXGJldGEgLTEpJCBpbnN0ZWFkOgoKIVtCaWFzIGluIHBlcmNlbnQgY2hhbmdlIGFwcHJveGltYXRpb25dKGJpYXNfcGN0Y2hhbmdlLnBuZykKCk5vdGU6IEEgVGF5bG9yIHNlcmllcyBleHBhbnNpb24gb2YgYW55IGZ1bmN0aW9uIGlzIGFuIGluZmluaXRlIHBvbHlub21pYWwgYXBwcm94aW1hdGlvbiBvZiB0aGF0IGZ1bmN0aW9uIGFib3V0IGEgY2VydGFpbiBwb2ludC4gVGhlIG1vcmUgaGlnaGVyIG9yZGVyIHRlcm1zIHdlIHVzZSwgdGhlIG1vcmUgY2xvc2VseSB3ZSBhcHByb3hpbWF0ZSB0aGUgb3JpZ2luYWwgZnVuY3Rpb24gZnVydGhlciBhd2F5IGZyb20gdGhlIHBvaW50LgoKUmVtZW1iZXIsIHdlIGFyZSBsb29raW5nIGF0IG5vbi1saW5lYXIgcmVsYXRpb25zaGlwLCBzbyBoZXJlIGFyZSB0d28gZm9ybXMgb2YgbG9nLWxpbiB2aXN1YWxpemVkCgo8aW1nIHNyYz0ibG9nbGluLnBuZyIgYWx0PSJkcmF3aW5nIiB3aWR0aD0iOTAwIi8+CgoKYGBge3J9CmxpYnJhcnkoIndvb2xkcmlkZ2UiLCAic3RhcmdhemVyIiwgInRpZHl2ZXJzZSIpCmRhdGEoYndnaHQpCmxvZ2xpbiA8LSBsbShsb2coYndnaHQpIH4gY2lncytmYW1pbmMsIGRhdGEgPSBid2dodCkKCiNzdGF0YSBlcXVpdmFsZW50CiMgZ2VuIGxuYndnaHQgPSBsbihid2dodCkKIyByZWcgbG5id2dodCBjaWdzIGZhbWluYwoKc3VtX2xvZ2xpbiA8LSBzdW1tYXJ5KGxvZ2xpbikKc3VtX2xvZ2xpbgoKI3N0YXRhIGVxdWl2YWxlbnQKI2VzdHN0byBsb2dsaW46IHJlZyBsbmJ3Z2h0IGNpZ3MgZmFtaW5jCiAKY2lnc2JldGEgPC0gZXhwKGxvZ2xpbiRjb2VmZmljaWVudHNbMl0pLTEKY2lnc2JldGEKZmFtaW5jIDwtIGV4cChsb2dsaW4kY29lZmZpY2llbnRzWzNdKS0xCmZhbWluYwpgYGAKRm9yIGV2ZXJ5IGFkZGl0aW9uYWwgZG9sbGFyIG9mIGZhbWlseSBpbmNvbWUgbGVhZHMgdG8gYW4gaW5jcmVhc2UgaW4gdGhlIGJhYnkncyBiaXJ0aCB3ZWlnaHQgYnkgLjA4JSAgKDAuMDAwOCoxMDApCgoKIyMjIyBMb2ctbG9nCiBXZSBjYW4gdXNlIHRoZSBsb2cgb24gYm90aCBzaWRlcyBvZiB0aGUgZXF1YXRpb24gdG8gZ2V0IGNvbnN0YW50IGVsYXN0aWNpdHkgbW9kZWxzLiBGb3IgZXhhbXBsZSwgaWYgCgokJFxsb2coYndnaHQpID1cYmV0YSBfezB9ICtcYmV0YSBfezF9IFxsb2coZmFtaW5jKSArdSQkIHRoZW4gCgokJFxiZXRhX3sxfSBcYXBwcm94IFxmcmFjeyBcJSBcRGVsdGEgYndnaHR9eyBcJSBcRGVsdGEgZmFtaW5jfSQkCgpUaGUgZWxhc3RpY2l0eSBpcyBmcmVlIG9mIHVuaXRzIG9mICRid2dodCQgYW5kICRmYW1pbmMkLiAKCldlIGNhbiBhbHNvIHNlZSB0aGlzIGFsZ2VicmFpY2FsbHk6CgpUYWtlIGEgc21hbGwgc2hpZnQgaW4gWCAkJCQkXGxvZyhid2dodCsgXERlbHRhIGJ3Z2h0KSA9XGJldGEgX3swfSArXGJldGEgX3sxfSBcbG9nKGZhbWluYyArIFxEZWx0YSBmYW1pbmMpICt1JCQgJCQKCnRoZW4gc3VidHJhY3QgJFxsb2coYndnaHQpID1cYmV0YSBfezB9ICtcYmV0YSBfezF9IFxsb2coZmFtaW5jKSArdSQgYW5kIHlvdSdsbCBnZXQ6CiQkXERlbHRhIGJ3Z2h0ID0gXGJldGFfMShcRGVsdGEgbG5mYW1pbmMpICQkClNvbHZlIGZvciAkXGJldGFfMSQ6CiQkXGJldGFfMSA9IFxmcmFje1xEZWx0YSBsbmJ3Z2h0fXtcRGVsdGEgbG5id2dodH0gXGFwcHJveGVxIFxmcmFje1xEZWx0YSBid2dodCAvYndnaHR9e1xEZWx0YSBmYW1pbmMvIGZhbWluY30kJApGb3IgYSAxJSB1bml0IGluY3JlYXNlIChkZWNyZWFzZSkgaW4gWCwgd2UgaGF2ZSAkXERlbHRh8J2Riz0wLjAxKOKIkjAuMDEpJCwgYW5kIHdlIGV4cGVjdCBhICRcYmV0YV8xXCUkIGluY3JlYXNlIChkZWNyZWFzZSkgaW4gWQoKCmBgYHtyfQpsb2dsb2cgPC0gbG0obG9nKGJ3Z2h0KSB+IGNpZ3MrbG9nKGZhbWluYyksIGRhdGEgPSBid2dodCkKc3VtX2xvZ2xvZyA8LSBzdW1tYXJ5KGxvZ2xvZykKc3VtX2xvZ2xvZwpgYGAKClRoZSBlc3RpbWF0ZWQgZWxhc3RpY2l0eSBvZiBid2dodCB3aXRoIHJlc3BlY3QgdG8gZmFtaWx5IGluY29tZSBpcyBhYm91dCAuMDE2IG9yIGEgMSUgY2hhbmdlIGluIGZhbWlseSBpbmNvbWUgaXMgYXNzb2NpYXRlZCB3aXRoIGEgLjAxNiUgaW5jcmVhc2UgaW4gYmlydGggd2VpaHQgKFRvIGludGVycHJldCB0aGlzIGVsYXN0aWNpdHksIHdlIGRvIG5vdCBuZWVkIHRvIGtub3cgJGJ3Z2h0JCBpcyBpbiBvdW5jZXMgd2hpbGUgJGZhbWluYyQgaXMgaW4gdGhvdXNhbmRzLikgCgpJdCBjb3VsZCBiZSBiZXR0ZXIgdG8gdGhpbmsgaW4gbGFyZ2VyIHRlcm1zICh3aG8gd2FudHMgYSAxJSBpbmNyZWFzZSBpbiBpbmNvbWU/KS0gYSAxMCBwZXJjZW50IGluY3JlYXNlIGluIGZhbWlseSBpbmNvbWUgbGVhZHMgdG8gYW4gaW5jcmVhc2UgaW4gYmlydGggd2VpZ2h0IGJ5IDEuNiUKCiQuMDE2ICgxMCkgPTEuNiQgcGVyY2VudCBpbmNyZWFzZSBpbiBmYW1pbHkgaW5jb21lLiAKCkhvdyBkbyB5b3UgaW50ZXJwcmV0IHRoZSBjb2VmZmljaWVudCBvZiBjaWdzPwoKRm9yIGV2ZXJ5IGFkZGl0aW9uYWwgY2lnYXJldHRlIHNtb2tlZCBvbiBhdmVyYWdlIHBlciBkYXkgaXMgYXNzb2NpYXRlZCB3aXRoIGEgLjQgXCUgIGluY3JlYXNlIGluIGJpcnRod2VpZ2h0LgoKSG93IGRvIHlvdSBpbnRlcnByZXQgdGhlIGludGVyY2VwdD8KCldlbGwsIGl0J3MgdHJpY2tpZXIgdG8gaW50ZXJwcmV0IHRoZSBsb2cgZGlyZWN0bHkuIFRoZSBpbnRlcmNlcHQgaXMgbm90IG1lYXN1cmluZyBhIGNoYW5nZSBpbiB2YWx1ZXMgLSBzbyBpdCdzIG5vdCBhIHBlcmNlbnQgY2hhbmdlICh0aGVyZSBpcyBubyBkaWZmZXJlbmNlIGluIGxvZ3MpLiBJdCdzIG11Y2ggZWFzaWVyIGp1c3QgdG8gZXhwb25lbnRpYXRlIHRoZSB2YWx1ZS4gU28sIHRvIGludGVycHJldCB0aGUgaW50ZXJjZXB0LCB3ZSBjYW4gZXhwb25lbnRpYXRlIGxpa2Ugc286CgpgYGB7cn0KZXhwKGxvZ2xvZyRjb2VmZmljaWVudHMpCmBgYApJbiB0aGlzIGNhc2UsIHRoZSBpbnRlcmNlcHQgaXMgMTEyLjAxIG91bmNlcy4gIExlYXZpbmcgaXQgaW4gbG9nIHVuaXRzIGlzIGtpbmQgb2Ygc3RyYW5nZSwgYmVjYXVzZSB3aGF0IGFyZSBsb2cgdW5pdHM/IE11Y2ggYmV0dGVyIHRvIGV4cG9uZW50aWF0ZSBpdCB0byBjb252ZXJ0IGl0IGJhY2sgdG8gdW5kZXJzdGFuZGFibGUgdW5pdHMuCgpUaGUgbG9nLW9uLWxvZyBjYXNlIHJlcHJlc2VudHMgYSBtdWx0aXBsaWNhdGl2ZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgb3JpZ2luYWwgdmFyaWFibGVzLiBGb3IgaW5zdGFuY2UKJCRsbnkgPSBcYmV0YV8wICtcYmV0YV8xbG54XzErXGJldGFfMmxueF8yK3VfaSQkCgppcyBlcXVpdmFsZW50IHRvIAokJHkgPSBlXntcYmV0YV8wfXhfMV57XGJldGFfMX14XzJee1xiZXRhXzJ9ZV57dX0gICAkJApWZXJ5IGNvbnZlbmllbnQhIFRoaW5rIG9mIGEgbGluZWFyaXplZCBDb2JiLURvdWdsYXMgcHJvZHVjdGlvbiBmdW5jdGlvbiAobWFjcm8pIQoKCgojIyMgbGluLWxvZwpJbiBhIGxpbiBsb2cgbW9kZWwsIAoKJCRid2dodCA9XGJldGFfezB9ICtcYmV0YV97MX0gXGxvZyhmYW1pbmMpICt1JCQKdGhlbiAKCiQkXGJldGEgX3sxfSBcYXBwcm94IFxmcmFjeyBcRGVsdGEgYndnaHR9eyBcRGVsdGEgbG9nKGZhbWluYyl9JCQKCldlIGNhbiBzZWUgdGhpcyBhbGdlYnJhaWNhbGx5LCB0b286CgpBZnRlciBhIHNtYWxsIHNoaWZ0IGluICRcRGVsdGEkZmFtaW5jIGluIGZhbWluYzoKJCRid2dodCA9IFxiZXRhXzAgKyBcYmV0YV8xbG4oZmFtaW5jICtcRGVsdGEgZmFtaW5jKSQkClN1YnRyYWN0IHRoaXMgZnJvbSBvdXIgZWFybGllciByZWdyZXNzaW9uLCAkYndnaHQgPVxiZXRhX3swfSArXGJldGFfezF9IFxsb2coZmFtaW5jKSArdSQKCmFuZCB5b3UgZ2V0OgoKJCQ9XGJldGFfMSBcRGVsdGEgbG5mYW1pbmMkJApTb2x2ZSBmb3IgJFxiZXRhXzEkCiQkXGJldGFfMSA9IFxmcmFje1xEZWx0YSBiZ3dodH17XERlbHRhIGxuZmFtaW5jfSBcYXBwcm94ZXEgXGZyYWN7XERlbHRhIGJnd2h0fXtcRGVsdGEgZmFtaW5jL2ZhbWluY30gPSAkJApGb3IgMSAlIGluY3JlYXNlIChkZWNyZWFzZSkgaW4gWCwgd2UgaGF2ZSBhICRcRGVsdGEgZmFtaW5jID0wLjAxKC0wLjAxKSQsIGFuZCB3ZSBleHBlY3QgYSAwLjAxICRcYmV0YV8xJCBpbmNyZWFzZSAoZGVjcmVhc2UpIGluIFkKCldlIGNhbiBzZWUgdGhlIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwIGZvciBhIGxvZy1saW4gd2l0aCBhIHBvc2l0aXZlIGxuKHgpIGFuZCBuZWdhdGl2ZSBsbih4KToKCjxpbWcgc3JjPSJsaW5sb2dwb3MucG5nIiBhbHQ9ImRyYXdpbmciIHdpZHRoPSIzMDAiLz4KPGltZyBzcmM9ImxpbmxvZ25lZy5wbmciIGFsdD0iZHJhd2luZyIgd2lkdGg9IjMyNSIvPgoKCmBgYHtyfQpsaW5sb2cgPC0gbG0oYndnaHQgfiBjaWdzK2xvZyhmYW1pbmMpLCBkYXRhID0gYndnaHQpCnN1bV9saW5sb2cgPC0gc3VtbWFyeShsaW5sb2cpCnN1bV9saW5sb2cKYGBgCgpGb3IgZXZlcnkgYWRkaXRpb25hbCAkMTAwMCBpbiBmYW1pbHkgaW5jb21lLCBiaXJ0aCB3ZWlnaHQgd2lsbCBpbmNyZWFzZSBieSAuMDE4ICUgKDEuOC8xMDApCgpvciByYXRoZXIsIGZvciBldmVyeSAkMTAsMDAwIGluY3JlYXNlIGluIGJpcnRoIHdlaWdodCBpcyBhc3NvY2lhdGVkIHdpdGggMTggb3VuY2VzICgoMS44LzEwMCkqMTAwMCkKCkxldCdzIGNvbXBhcmUgb3VyIGVzdGltYXRlcyBvZiB0aGUgbW9kZWxzCgoKYGBge3IsIHJlc3VsdHM9J2FzaXMnfQpsaWJyYXJ5KCJzdGFyZ2F6ZXIiKQpsaW5saW4gPC0gbG0oYndnaHQgfiBjaWdzICsgZmFtaW5jLCBkYXRhID0gYndnaHQpCnN1bV9saW5saW4gPC0gc3VtbWFyeShsaW5saW4pCgpzdGFyZ2F6ZXIoIGxvZ2xvZywgbG9nbGluLCBsaW5sb2csIGxpbmxpbiwgdHlwZSA9ICJodG1sIiwKICAgICAgICAgICByZXN1bHRzID0gJ2FzaXMnLG1lc3NhZ2UgPSBGQUxTRSwgZWNobyA9IEZBTFNFLCBub3Rlcy5hcHBlbmQgPSBGQUxTRSwgaGVhZGVyID0gRkFMU0UsIHNpbmdsZS5yb3cgPSBUUlVFKQoKCgpgYGAKV2hhdCBjYW4gd2UgY29tcGFyZT8gCgpUaGUgU0VSIChzdGFuZGFyZCBlcnJvciBvZiB0aGUgcmVncmVzc2lvbikgaXMgaW4gdGhlIGRlcGVuZGVudCB1bml0cy4gVGhpcyBtZWFucyB0aGF0IHdlIGNhbiBjb21wYXJlIHRoZSBmaXQgb2YgdGhlIG1vZGVscyBsaW4tbG9nIGFuZCBsaW4tbG9nIG1vZGVscywgYnV0ICAqbm90KiBhbnkgb2YgdGhlIG1vZGVscyB0aGF0IGhhdmUgdGhlIGxvZyBpbiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlcy4KCkluIGFkZGl0aW9uLCB0aGUgJFIkLXNxdWFyZWQgaXMgbm90IGRpcmVjdGx5IGNvbXBhcmFibGUuIFRoZSB0b3RhbCB2YXJpYXRpb24gKFNTVHMpIGluICRid2VpZ2h0X3tpfSQgYW5kICRsIGJ3ZWlnaHRfe2l9JCB0aGF0IHdlIG11c3QgZXhwbGFpbiBhcmUgY29tcGxldGVseSBkaWZmZXJlbnQuIAoKCkEgaGFuZHkgcmVtaW5kZXIgb2YgaW50ZXJwcmV0aW5nIGNvZWZmaWNpZW50cyBpczoKCnwgICAgTW9kZWwgIHxEZXAuIFZhciB8IEluZGVwLiBWYXIgfCAkXGJldGFfMSR8CnwtLS0tLS0tLS0tLXwtLS0tLS0tLS18LS0tLS0tLS0tLS0tfC0tLS0tLS0tLS18CnxMaW4tTGlufCB5ICAgICAgIHx4ICAgICAgICAgICB8JFxEZWx0YSB5PVxiZXRhXzEgXERlbHRhIHgkCnwgTGluLUxvZyB8IHkgICAgICAgfGxvZyh4KSAgICAgIHwkXERlbHRhIHk9KFxiZXRhXzEvMTAwXCUpIFxEZWx0YSB4JAp8IExvZy1MaW4gfGxvZyh5KSAgIHx4ICAgICAgICAgICB8JFwlXERlbHRhIHk9KDEwMFxiZXRhXzEpIFxEZWx0YSB4JCAgdGVjaG5pY2FsbHkgc2hvdWxkIGJlICQxMDAgKiAoZV5cYmV0YS0xKSBcRGVsdGEgeCQKfCAgTG9nLUxvZyAgfGxvZyh5KSAgIHxsb2coeCkgICAgICB8JFxEZWx0YSBcJXk9XGJldGFfMVxEZWx0YSB4JAoKVGhlIHBvc3NpYmlsaXR5IG9mIHVzaW5nIHRoZSBuYXR1cmFsIGxvZyB0byBnZXQgbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzIGJldHdlZW4gJHkkIGFuZCAkeCQgcmFpc2VzIGEgcXVlc3Rpb246IFdoYXQgZG8gd2UgbWVhbiBub3cgYnkgYGBsaW5lYXInJyByZWdyZXNzaW9uPyAKClRoZSBhbnN3ZXIgaXMgdGhhdCB0aGUgbW9kZWwgaXMgbGluZWFyIGluIHRoZSBcdGV4dGl0e3BhcmFtZXRlcnN9LCAkXGJldGEgX3swfSQgYW5kICRcYmV0YSBfezF9JC4gV2UgY2FuIHVzZSBhbnkgdHJhbnNmb3JtYXRpb25zIG9mIHRoZSBkZXBlbmRlbnQgYW5kIGluZGVwZW5kZW50IHRvIGdldCBpbnRlcmVzdGluZyBpbnRlcnByZXRhdGlvbnMgZm9yIHRoZSBwYXJhbWV0ZXJzLiAKCiMjIyMgIFN0YW5kYXJkaXplZCBjb2VmZmljaWVudHMKQ29uZnVzaW5nbHksIGEgYmV0YSBjb2VmZmljaWVudCBpcyBhIHN0YW5kYXJkaXplZCBjb2VmZmljaWVudC4gV2UgdXNlIGJldGEgaGF0IHRvIGRlbm90ZSBvdXIgT0xTIGVzdGltYXRlLiBGb3IgdGhlIHNha2Ugb2YgdGhpcyBjb3Vyc2UsIHdlIHdpbGwgY29udGludWUgdXNpbmcgdGhlIHRlcm0gc3RhbmRhcmRpemVkIGNvZWZmaWNpZW50IHdoZW4gd2Ugc3RhbmRhcmRpemUgeSBhbmQgZWFjaCAkeF9qJCBieSBzdWJ0cmFjdGluZyBpdHMgbWVhbiBhbmQgZGl2aWRpbmcgYnkgaXRzIHNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb24uCgpUaGlzIGNhbiBiZSB1c2VmdWwgd2hlbiBzb21lIG9mIHRoZSAkeF9qJCBvciB5IGhhdmUgdW5pdHMgdGhhdCBhcmUgbm90IGVhc2lseSB1bmRlcnN0b29kLiBTbywgZm9yIGV4YW1wbGUsIHdlIG1pZ2h0IG5vdCBoYXZlIGEgZ29vZCBzZW5zZSBmb3IgaG93IGltcG9ydGFudCBpcyBhbiBpbmNyZWFzZSBpbiBhIHRlc3Qgc2NvcmUgYnkgb25lIHBvaW50LiBVc2luZyBsb2dzIGdpdmVzIHVzIHBlcmNlbnRhZ2UgZWZmZWN0cywgYnV0IHdlIGRvIG5vdCBhbHdheXMgd2FudCB0byBkbyB0aGF0LgoKSXQgaXMgb2Z0ZW4gdXNlZnVsIHRvIGFzayB0aGUgZm9sbG93aW5nIHF1ZXN0aW9uLCB3aGljaCBhbGxvd3MgdXMgdG8gc2VlIGhvdyBpbXBvcnRhbnQgYW4gZWZmZWN0IGlzIHJlbGF0aXZlIHRvIHRoZSBwb3B1bGF0aW9uOiDigJxIb3cgbWFueSBzdGFuZGFyZCBkZXZpYXRpb25zIHdpbGwgeSBjaGFuZ2Ugd2hlbiAkeF9qJCBpbmNyZWFzZXMgYnkgb25lIHN0YW5kYXJkIGRldmlhdGlvbj/igJ0KCldoZW4geW91IHN0YW5kYXJkaXplLCB0aGVyZSBpcyBubyBiZXRhIGNvZWZmaWNpZW50IGZvciB0aGUgaW50ZXJjZXB0IGJlY2F1c2UgdGhlIGludGVyY2VwdCBpcyB6ZXJvIHdoZW4gYWxsIHZhcmlhYmxlcyBoYXZlIHplcm8gc2FtcGxlIGF2ZXJhZ2VzLgoKYGBge3J9CmxpYnJhcnkoImRwbHlyIikKCmRhdGEoYXR0ZW5kKQojIElmIHlvdSB3YW50IHRvIHN0YW5kYXJkaXplIHlvdXIgb3duIHZhbHVlcywgeW91IGNhbiBkbyBzbyBhcyBzdWNoLiBJIGFtIHN0YW5kYXJkaXppbmcgR1BBIGFuZCBBQ1QgaW4gdGhpcyBjYXNlIGFuZCBjcmVhdGluZyBhIE5FVyBkYXRhZnJhbWUuIFRoaXMgd2lsbCByZXBsYWNlIHRoZSBleGlzdGluZyBjb2x1bW5zIC0gc28gYmUgYXdhcmUgb2YgdGhhdCBpbiB0aGlzIG1ldGhvZCEKYXR0ZW5kc3RkIDwtIGF0dGVuZCAlPiUgbXV0YXRlX2F0KGMoJ3ByaUdQQScsICdBQ1QnKSwgfihzY2FsZSguKSAlPiUgYXMudmVjdG9yKSkKCgoKYXR0ZW5kX3N0ZCA8LSBsbShzdG5kZm5sIH4gbWlzc2VkK3ByaUdQQStBQ1QsIGRhdGEgPSBhdHRlbmRzdGQpCgpzdW1tYXJ5KGF0dGVuZF9zdGQpCgoKYGBgCgpUaGUgY29lZmZpY2llbnQgb24gcHJpR1BBIGlzIGxhcmdlciB0aGFuIG9uIEFDVCBieSBhbG1vc3QgYSBmYWN0b3Igb2YgZml2ZS4gQnV0IGRvZXMgdGhpcyBtZWFuIHByaUdQQSBoYXMgdGhlIG1vcmUgaW1wb3J0YW50IGVmZmVjdD8KCkFuIGluY3JlYXNlIGluIG9uZSBzZCBvZiBwcmlHUEEgaW5jcmVhc2VzIGZpbmFsIGJ5IGFib3V0IC4yMTkgc2RzIHdoaWxlIGEgb25lIHNkIGluY3JlYXNlIGluIEFDVCBpbmNyZWFzZXMgZmluYWwgYnkgYWJvdXQgLjI5NCBzZHMsIHdoaWNoIGlzIGEgbGFyZ2VyIG1vdmVtZW50IGluIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMuCgojIyBRdWFkcmF0aWMvUG9seW5vbWlhbCBGdW5jdGlvbnMKVXNpbmcgdGhlIGxvZyBvZiBhbiBpbmRlcGVuZGVudCB2YXJpYWJsZSBpcyBvbmUgd2F5IHRvIGdldCBhIGRpbWluaXNoaW5nIGVmZmVjdC4gQnV0IHNvbWV0aW1lcyBpdCBpcyBub3QgZmxleGlibGUgZW5vdWdoLgoKTW9kZWxzIHdpdGggcXVhZHJhdGljcyBjYW4gZGVsaXZlciBpbmNyZWFzaW5nIG9yIGRlY3JlYXNpbmcgZWZmZWN0cy4gUGx1cywgdGhleSBjb250YWluIHRoZSBjb25zdGFudCBlZmZlY3QgYXMgYSBzcGVjaWFsIGNhc2UsIHdoaWNoIGNhbiBiZSBlYXNpbHkgdGVzdGVkLgoKTW9kZWxzIGFsc28gYWxsb3cgZm9yIGEgdHVybmluZyBwb2ludCwgd2hpY2ggaXMgc29tZXRpbWVzIG9mIGludGVyZXN0LiAoRm9yIGV4YW1wbGUsIHdoYXQgaXMgdGhlIG9wdGltYWwgbnVtYmVyIG9mIHN0dWRlbnRzIGF0IGEgaGlnaCBzY2hvb2wgZm9yIGhpZ2ggc2Nob29sIHBlcmZvcm1hbmNlPykKCkNvbnNpZGVyIHRoZSBtb2RlbAoKJCR5ID0gzrJfMCArIM6yXzF4XzEgKyDOsl8yeF8xXjIgKyB1JCQKClRoZXJlIGlzIG9ubHkgYSBzaW5nbGUgZXhwbGFuYXRvcnkgdmFyaWFibGUsIHgsIGJ1dCB0d28gcmVncmVzc29ycywgJHhfMSwgeF8yJC4KClRoZSBzbG9wZSBvZiB5IHdpdGggcmVzcGVjdCB0byB4IGRlcGVuZHMgb24gJFxiZXRhXzEkIGFuZCAkXGJldGFfMiQsIGFuZCB0aGUgdmFsdWUgb2YgeDogJCBcZnJhY3tkeX17ZHh9ID0gXGJldGFfMSArIDJcYmV0YV8yeCQgaG9sZGluZyB1IGZpeGVkIAoKRXN0aW1hdGlvbiBpcyBzdHJhaWdodGZvcndhcmQuIFdlIGp1c3QgZGVmaW5lIGEgbmV3IHZhcmlhYmxlLCAkeF4yJCwgYW5kIGluY2x1ZGUgaXQgYWxvbmcgd2l0aCB4IGFzIGEgcmVncmVzc29yLgoKSGF2aW5nIGVzdGltYXRlZCB0aGUgY29lZmZpY2llbnRzIHdlIHdyaXRlCiQkIFxoYXR7eX0gPSBcaGF0e1xiZXRhXzB9K1xoYXR7XGJldGFfMX14K1xoYXR7XGJldGFfMn14XjIgJCQKCiQkClxmcmFje1xEZWx0YXtcaGF0e3l9fX17XERlbHRhIFh9IFxhcHByb3ggXGhhdHtcYmV0YV8xfStcaGF0e1xiZXRhXzJ9MlgKJCQKCkNhc2VzCgoxLiBJZiAkXGhhdHtcYmV0YV8xfSA+IDAkIGFuZCAkXGhhdHtcYmV0YV8yfSA8IDAkLCB0aGUgc2xvcGUgaXMgaW5pdGlhbGx5IHBvc2l0aXZlLCBidXQgaXQgZGVjcmVhc2VzIGFzIHggaW5jcmVhc2VzLiBUaGUgZnVuY3Rpb24gaGFzIGEgaHVtcCBzaGFwZSBhbmQgdHVybnMgYXQgdGhlIHZhbHVlCgokJCAgXGRpc3BsYXlzdHlsZVxsZWZ0XGx2ZXJ0IHheKiA9IHtcZnJhY3tcaGF0e1xiZXRhXzF9fXsyIFxoYXR7XGJldGFfMn19fSBccmlnaHRccnZlcnQgJCQKCnRoZSBtYXhpbXVtIG9mIHRoZSBmdW5jdGlvbi4gQWZ0ZXIgdGhlIHZhbHVlIHjiiJcsIHRoZSBzbG9wZSBpcyBuZWdhdGl2ZS4KCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKcXVhZHJhdGljIDwtIGZ1bmN0aW9uKHgpe3gteF4yfQoKI3Bsb3QgaXQKZ2dwbG90KGRhdGEuZnJhbWUoeCA9IGMoLTE1LDE1KSksIGFlcyh4ID0geCkpICsKICBzdGF0X2Z1bmN0aW9uKGZ1biA9IHF1YWRyYXRpYykgKyB4bGltKGMoLTE1LCAxNSkpIApgYGAKCgoKCjIuIElmICRcaGF0e1xiZXRhXzF9IDwgMCQgIGFuZCAkXGhhdHtcYmV0YV8yfSA+IDAkLCB0aGUgc2xvcGUgaXMgaW5pdGlhbGx5IG5lZ2F0aXZlLCBidXQgaXQgaW5jcmVhc2VzIChnZXRzIGxlc3MgbmVnYXRpdmUpIGFzIHggaW5jcmVhc2VzLiBUaGUgZnVuY3Rpb24gaGFzIGEgVSBzaGFwZSBhbmQgdHVybnMgYXQgdGhlIHjiiJcgZ2l2ZW4gYWJvdmUuIEJ1dCBub3cgeOKIlyBpcyB0aGUgbWluaW11bSBvZiB0aGUgZnVuY3Rpb24uIE9uY2UgJHggPiB44oiXJCwgdGhlCnNsb3BlIGlzIHBvc2l0aXZlLgpgYGB7cn0KcXVhZHJhdGljIDwtIGZ1bmN0aW9uKHgpey14K3heMn0KCiNwbG90IGl0CmdncGxvdChkYXRhLmZyYW1lKHggPSBjKC0xNSwxNSkpLCBhZXMoeCA9IHgpKSArCiAgc3RhdF9mdW5jdGlvbihmdW4gPSBxdWFkcmF0aWMpICsgeGxpbShjKC0xNSwgMTUpKSAKCgojY3VydmUoLXgreF4yICwgZnJvbT0xLCB0bz0xMCwgbj0zMDAsIHhsYWI9Inh2YWx1ZSIsIHlsYWI9Inl2YWx1ZSIsIAogIyAgICAgICAgICAgIGNvbD0iYmx1ZSIsIGx3ZD0yLCBtYWluPWV4cHJlc3Npb24oaGF0KGJldGFbMV0pPDAgfiAiLCIgfmhhdChiZXRhWzJdKT4wKSkKYGBgCgpJbiBDYXNlcyAxIGFuZCAyLCB3ZSBzaG91bGQgYXNrOiBEb2VzIHRoZSB0dXJuaW5nIHBvaW50IG1ha2VzIHNlbnNlPyBJZiBpdCBkb2VzIG5vdCBtYWtlIHNlbnNlIGZvciB0aGUgc2xvcGUgdG8gY2hhbmdlIHNpZ25zLCBkb2VzIHRoZSBzaWduIGNoYW5nZSBoYXBwZW4gb25seSBhdCBhbiBleHRyZW1lIHZhbHVlIG9mIHg/CgozLiBJZiAkXGhhdHtcYmV0YV8xfSA+IDAkICBhbmQgJFxoYXR7XGJldGFfMn0gPiAwJCwgdGhlIHNsb3BlICgkXGhhdHtcYmV0YV8xfSsyXGhhdHtcYmV0YV8yfXgkKSBpcyBhbHdheXMgcG9zaXRpdmUgYW5kIGluY3JlYXNlcyB3aXRoIHguIFRoZSB0dXJuaW5nIHBvaW50IG9jY3VycyBhdCBhIG5lZ2F0aXZlIHZhbHVlIG9mIHguIChJbiBwcmFjdGljZSwgbGVzcyBjb21tb24gdGhhbiBDYXNlIDEuKQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQoKCmN1cnZlKCAgeCt4XjIgLCBmcm9tPTEsIHRvPTEwLCBuPTMwMCwgeGxhYj0ieHZhbHVlIiwgeWxhYj0ieXZhbHVlIiwgCiAgICAgICAgICAgICBjb2w9ImJsdWUiLCBsd2Q9MiwgbWFpbj1leHByZXNzaW9uKGhhdChiZXRhWzFdKT4wIH4gIiwiIH5oYXQoYmV0YVsyXSk+MCkpCmBgYAo0LiBJZiAkXGhhdHtcYmV0YV8xfSA8IDAkICBhbmQgJFxoYXR7XGJldGFfMn0gPCAwJCwgdGhlIHNsb3BlIGlzIGFsd2F5cyBuZWdhdGl2ZSBhbmQgYmVjb21lcyBtb3JlIG5lZ2F0aXZlIChpbmNyZWFzZXMgaW4gYWJzb2x1dGUgdmFsdWUpIGFzIHggaW4gY3JlYXNlcy4gVGhlIHR1cm5pbmcgcG9pbnQgaXMgbmVnYXRpdmUuCgpBZGRpbmcgYWRkaXRpb25hbCBleHBsYW5hdG9yeSB2YXJpYWJsZXMgY2hhbmdlcyBub3RoaW5nIG9mIHRoZSBjYWxjdWxhdGlvbnMsIGV4Y2VwdCBmb3IgZ2l2aW5nIGEgY2V0ZXJpcyBwYXJpYnVzIGludGVycHJldGF0aW9uLgoKYGBge3J9CgojcGxvdCBpdApjdXJ2ZSggIC14LXheMiAsIGZyb209MSwgdG89MTAsIG49MzAwLCB4bGFiPSJ4dmFsdWUiLCB5bGFiPSJ5dmFsdWUiLCAKICAgICAgICAgICAgIGNvbD0iYmx1ZSIsIGx3ZD0yLCBtYWluPWV4cHJlc3Npb24oaGF0KGJldGFbMV0pPDAgfiAiLCIgfmhhdChiZXRhWzJdKTwwKSkKYGBgCgoKYGBge3J9CmRhdGEod2FnZTEpCndhZ2UxJGV4cGVyMiA8LSB3YWdlMSRleHBlcl4yCndhZ2Vfc3F1YXJlIDwtIGxtKGxvZyh3YWdlKSB+ZWR1YyArIGV4cGVyICsgZXhwZXIyICwgZGF0YSA9IHdhZ2UxKQpzdW1tYXJ5KHdhZ2Vfc3F1YXJlKQoKYGBgCgpUaGUgZXN0aW1hdGVkIHJldHVybiB0byBlZHVjYXRpb24gaXMgOS4wJS4gVGhlIG1vZGVsIGFzc3VtZXMgdGhpcyBpcwp0aGUgc2FtZSBmb3IgYWxsIHllYXJzIG9mIGV4cGVyaWVuY2UgYW5kIGVkdWNhdGlvbi4KCkJ5IGNvbnRyYXN0LCBlYWNoIHllYXIgb2YgZXhwZXJpZW5jZSBpcyB3b3J0aCBsZXNzIHRoYW4gdGhlIHByZWNlZGluZyB5ZWFyLiBUaGUgc2xvcGUgaXMsIHVzaW5nIGNhbGN1bHVzIOKAkyBqdXN0IHRha2UgdGhlIGRlcml2YXRpdmUgd2l0aCByZXNwZWN0IHRvIGV4cGVyIOKAkyBpcwpcYmVnaW57ZXF1YXRpb259ClxmcmFje1xEZWx0YSBcaGF0e2x3YWdlfX17XERlbHRhIGV4cGVyfSBcYXBwcm94IC4wNDEg4oiSIDIoLjAwMDcpZXhwZXIgPSAuMDQxIOKIkiAuMDAxNGV4cGVyClxlbmR7ZXF1YXRpb259CgpDYW4gdGhpbmsgb2YgMTIuNyUgKHRoZSAkXGJldGFfMCQpIGFzIGFwcHJveGltYXRlbHkgdGhlIHJldHVybiB0byB0aGUgZmlyc3QgeWVhciBvZiBleHBlcmllbmNlIOKAkyBlc3NlbnRpYWxseSBzdGFydGluZyBvZmYgaW4gdGhlIHdvcmtmb3JjZS4gVGhlIHJldHVybiBpbiBnb2luZyBmcm9tIDEwIHRvIDExIGlzIGFib3V0CiQuMDQxIOKIkiAuMDM5NioxMCA9IC0uMzU1JApvciAyLjclLgoKCldlIGNvdWxkIGJlIG1vcmUgcHJlY2lzZSBhbmQgbm90IHVzZSBhIGNhbGN1bHVzIGFwcHJveGltYXRpb246ICRbLjA0MSgxMSkg4oiSIC4wMDA3KDExKV4yXSDiiJIgWy4wNDEoMTApIOKIkiAuMDAwNygxMCleMl0gXGFwcHJveCAyLjYzJCwgd2hpY2ggaXMgcmVhc29uYWJseSBjbG9zZS4KCkJlY2F1c2UgdGhlIHF1YWRyYXRpYyBtb2RlbCBpcyBtb3JlIGNvbXBsaWNhdGVkIHRvIGludGVycHJldCBhbmQgZXhwbGFpbiwgd2Ugc2hvdWxkIG1ha2Ugc3VyZSB0aGVyZSBpcyBnb29kIHN0YXRpc3RpY2FsIGV2aWRlbmNlIGZvciBrZWVwaW5nICR4XzIkIChleHBlcjIpIGluIHRoZSBlcXVhdGlvbi4KClNvLCB3ZSB0ZXN0IHRoZSBudWxsIHRoYXQgdGhlIGVxdWF0aW9uIGlzIGxpbmVhciBpbiBleHBlciBhZ2FpbnN0IHRoZSBhbHRlcm5hdGl2ZSB0aGF0IGl0IGlzIHF1YWRyYXRpYzoKXGJlZ2lue2VxdWF0aW9ufQpIXzAgPSBcYmV0YV97ZXhwZXIyfSA9IDAKXGVuZHtlcXVhdGlvbn0KXGJlZ2lue2VxdWF0aW9ufQpIX0EgPSBcYmV0YV97ZXhwZXIyfSBcbmVxIDAKXGVuZHtlcXVhdGlvbn0KCkltcG9ydGFudDogJM6yX3tleHBlcn0kIGlzIG5vdCByZXN0cmljdGVkLiBTbyB3ZSB1c2UgYSB0IHRlc3Qgb24gZXhwZXIyLgoKVGhlIHQgaW4gdGhpcyBleGFtcGxlIGlzIC02LjE2NCB3aXRoIHR3by1zaWRlZCBwLXZhbHVlID0gLjAwMDEsIHNvIHdlIHJlamVjdCBIMCBhdCB0aGUgNSUgbGV2ZWwuIEl0IHNlZW1zIGEgZ29vZCBpZGVhIHRvIGtlZXAgZXhwZXIyIGluIHRoZSBlcXVhdGlvbi4KCkhvd2V2ZXIsIGlmIHdlIHdhbnQgdG8gdGVzdCBpZiBleHBlcmllbmNlIGhhcyBhbiBlZmZlY3Qgb24gd2FnZXM6ClRoaXMgd291bGQgYmUKXGJlZ2lue2VxdWF0aW9ufQpIXzA6IFxiZXRhX3tleHBlcn0gPSAwLCBcYmV0YV97ZXhwZXJeMn0gPSAwClxlbmR7ZXF1YXRpb259CldlIHdvdWxkIHVzZSBhbiBGIHRlc3QuIEJ1dCB1c3VhbGx5LCBpZiB0aGUgcXVhZHJhdGljIHRlcm0gaXMgaW5zaWduaWZpY2FudCwgd2UgZ28gYmFjayB0byBhIGxpbmVhciBtb2RlbC4KIAogV2UgY2FuIGFsc28gZmluZCB0aGUgInBlYWsiIG9yICJ0cm91Z2giIGJ5IHNldHRpbmcgb3VyIEZPQyAoZmlyc3Qgb3JkZXIgY29uZGl0aW9ucykgdG8gMCBhbmQgc29sdmluZyBmb3IgWC4KIAogCiAkMCA9IC4wNDEg4oiSIDIoLjAwMDcpZXhwZXIkCiAKICRleHBlciA9IC4wNDEvLjAwMTQgPSAyOS4yOSQKIAogQWZ0ZXIgd29ya2luZyBmb3IgMjkuMjkgeWVhcnMsIHRoZSBtYXJnaW5hbCBpbmNyZWFzZSBvZiBzYWxhcnkgYmVnaW5zIHRvIGRlY2xpbmUuIAogCiAKIFdpdGggY2FsY3VsdXMsIHdlIGNhbiBhbHNvIHNheSBzb21ldGhpbmcgYWJvdXQgd2hldGhlciB0aGUgZWZmZWN0IGlzIGdvaW5nIHRvIG1hcmdpbmFsbHkgaW5jcmVhc2Ugb3IgbWFyZ2luYWxseSBkZWNyZWFzZS4gIFdlIGp1c3QgdGFrZSB0aGUgc2Vjb25kIGRlcml2YXRpdmUgb2Ygb3VyIG1hcmdpbmFsIGVmZmVjdHMgZXF1YXRpb24gYW5kIHNlZSBpZiB0aGUgcmVzdWx0IGlzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlLiBUaGlzIGJhc2ljYWxseSB0ZWxscyB1cyBpZiBhZnRlciB0aGUgcGVhayBvciB0cm91Z2gsIGRvZXMgdGhlIHZhbHVlIGdvIHVwIG9yIGRvd24uICBBbmQgd2UgY2FuIHNlZSB0aGF0IHRoZSBzZWNvbmQgZGVyaXZhdGl2ZSBvZiBleHBlciBpcyBuZWdhdGl2ZS4KICAKCkJ1dCwgZXZlbiBtb3JlIHNpbXBseSwgd2UgY2FuIGp1c3QgbG9vayBhdCB0aGUgc2lnbiBvZiB0aGUgc3F1YXJlZCB0ZXJtLiBBIHBvc2l0aXZlIHRlcm0gd2lsbCB0ZWxsIHVzIHRoYXQgdGhlIG1hcmdpbmFsIGVmZmVjdCBpbmNyZWFzZXMsIHdoaWxlIGEgbmVnYXRpdmUgdGVybSB3aWxsIHRlbGwgdXMgdGhhdCB0aGUgbWFyZ2luYWwgZWZmZWN0IGRlY3JlYXNlcy4KIAogTGV0J3MgZ3JhcGhpY2FsbHkgdmlzdWFsaXplIHRoZXNlIHJlc3VsdHM6CmBgYHtyfQoKbGlicmFyeSh3b29sZHJpZGdlKQojaW5zdGFsbC5wYWNrYWdlcygibWFyZ2lucyIpCmxpYnJhcnkobWFyZ2lucykKCgpsbShsb2cod2FnZSkgfmVkdWMgKyBzdGF0czo6cG9seShleHBlciwgMikgLCBkYXRhID0gd2FnZTEpCiMgd2UgaGF2ZSB0byB1c2UgdGhlIHBvbHkgZnVuY3Rpb24gdG8gZ2V0IHRoZSBjb3JyZWN0IG1hcmdpbmFsIGVmZmVjdHMgZ3JhcGgKCndhZ2Vfc3F1YXJlIDwtIGxtKGxvZyh3YWdlKSB+ZWR1YyArIGV4cGVyICsgSShleHBlcl4yKSAsIGRhdGEgPSB3YWdlMSkKCnN1bW1hcnkod2FnZV9zcXVhcmUpCmNwbG90KHdhZ2Vfc3F1YXJlLCAiZXhwZXIiKQoKIyBXZSBjYW4gdGFrZSB0aGUgYXZlcmFnZSBvZiB0aGUgbWFyZ2luYWwgZWZmZWN0IHdpdGg6CnN1bW1hcnkobWFyZ2lucyh3YWdlX3NxdWFyZSwgdmFyaWFibGVzID0gImV4cGVyIikpCgojd2UgY2FuIGFsc28gZXh0cmFjdCB0aGUgbWFyZ2luYWwgZWZmZWN0IGluIGEgdGFibGU6CmR5ZHgod2FnZTEsIHdhZ2Vfc3F1YXJlLCB2YXJpYWJsZSA9ICJleHBlciIpCgojYXQgc3BlY2lmaWMgdmFsdWVzCnN1bW1hcnkobWFyZ2lucyh3YWdlX3NxdWFyZSwgYXQgPSBsaXN0KGV4cGVyID0gYygxMCwgMTUsIDIwLCAyNSwgMzAsIDM1LCA0MCkpLCB2YXJpYWJsZXMgPSAiZXhwZXIiKSkKCm1lYW4od2FnZTEkZXhwZXIpCgpgYGAKClJlY2FsbCB0aGF0IGlmIHlvdSBoYXZlIG11bHRpcGxlIHZhcmlhYmxlcyB0aGF0IGFyZSBoaWdobHkgY29ycmVsYXRlZCB0aGF0IHlvdXIgaW5mZXJlbmNlIHdpbGwgY2hhbmdlLiBXZWxsLCB0aGF0J3Mgbm8gZGlmZmVyZW50IGhlcmUgLSB5b3UgY2FuIGltYWdpbmUgdGhhdCAkeCQgYW5kICR4XjIkIGFyZSBoaWdobHkgY29ycmVsYXRlZAoKVG8gc2VlIGlmIGV4cGVyaWVuY2UgaGFzIGEgKnN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZWZmZWN0KiBvbiB3YWdlcywgd2UgbXVzdCBjb25kdWN0IGFuIGYgdGVzdCBvbiBhbGwgb2YgdGhlIHRlcm1zIGFzc29jaWF0ZWQgd2l0aCBleHBlcmllbmNlLgoKTGV0J3MgZG8gdGhhdCBmLXRlc3QKCmBgYHtyfQpsaWJyYXJ5KGNhcikKCgpsaW5lYXJIeXBvdGhlc2lzKHdhZ2Vfc3F1YXJlLCBjKCJleHBlcj0wIiwgIkkoZXhwZXJeMik9MCIpKQoKYGBgCkluZGVlZCwgZXhwZXJpZW5jZSBoYXMgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGVmZmVjdC4gV2UgcmVqZWN0IHRoZSBudWxsIGF0IHRoZSAxJSBsZXZlbC4KCgpXZSBjYW4gYWxzbyBzZWUgaG93IHRoZSBsaW5lYXIgdnMuIHF1YWRyYXRpYyBmaXQgY2hhbmdlcwpgYGB7cn0KZGF0YSh3YWdlMSkKCiNMZXQncyBncmFwaCB0aGUgc2ltcGxlIHJlZ3Jlc3Npb24gbGluZSBkaWZmZXJlbmNlcwoKbGlicmFyeSh0aWR5dmVyc2UpCmdncGxvdCh3YWdlMSwgYWVzKHg9ZXhwZXIsIHk9d2FnZSkpKwogIGdlb21fcG9pbnQoKSArCiAgc3RhdF9zbW9vdGgoYWVzKHkgPSB3YWdlKSxtZXRob2QgPSAibG0iLCBmb3JtdWxhID0geSB+IHggLCBjb2xvcj0gInJlZCIpICsKICBzdGF0X3Ntb290aChhZXMoeT13YWdlKSwgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IHkgfiB4ICsgSSh4XjIpKSAKCgojV2UgY2FuIGFkZCBjb250cm9scyBhbmQgbG9vayBhdCB0aGUgZGlmZmVyZW5jZXMgaW4gdGhlIHJlZ3Jlc3Npb24Kd2FnZV9saW4gPC0gbG0od2FnZSB+ZWR1YyArIGV4cGVyLCBkYXRhID0gd2FnZTEpCndhZ2VfcXVhZCA8LSBsbSh3YWdlIH5lZHVjICsgZXhwZXIgK0koZXhwZXJeMiksIGRhdGEgPSB3YWdlMSkKCgpgYGAKCiMjIEludGVyYWN0aW9uIFRlcm1zCgpUaGUgcXVhZHJhdGljIGlzIG5vdCB2ZXJ5IGRpZmZlcmVudCBmcm9tIGludGVyYWN0aW9uIHRlcm1zIGluIG1lY2hhbmljYWwgdGVybXMsIHlvdSBqdXN0IGhhdmUgdG8gYmUgY2FyZWZ1bCBvZiBpbnRlcnByZXRhdGlvbiBhbmQgdGVzdGluZyAtIGJlY2F1c2UgdGhlIHR3byB0ZXJtcyBkZXBlbmQgb24gb25lIGFub3RoZXIuCgpTdXBwb3NlIHdlIGhhdmUgdHdvIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBhbmQgc3RhcnQgd2l0aCB0aGUgdXN1YWwgbW9kZWw6IAoKJCR5ID0gzrJfMCArIM6yXzF4XzEgKyDOsl8yeF8yICsgdSQkCgpUaGUgcGFydGlhbCBlZmZlY3Qgb2YgJHhfMSQgb24geSBpcyAkzrJfMSQgYW5kIHRoZSBQRSBvZiAkeF8yJCBvbiB5IGlzICTOsl8yJC4gRXZlbiBpZiB3ZSBhZGQgcXVhZHJhdGljcywgdGhlIG1vZGVsIGhhcyBhIHBvdGVudGlhbGx5IGltcG9ydGFudCByZXN0cmljdGlvbjogdGhlIHBhcnRpYWwgZWZmZWN0IG9mICR4XzEkIG5ldmVyIGRlcGVuZHMgb24gJHhfMiQsIGFuZCB2aWNlIHZlcnNhLgoKU29tZXRpbWVzIGl0IGlzIG5hdHVyYWwgdG8gdGhpbmsgdGhlIHBhcnRpYWwgZWZmZWN0IG9mIG9uZSB2YXJpYWJsZSwgc2F5IGVkdWNhdGlvbiwgY291bGQgZGVwZW5kIG9uIHRoZSBsZXZlbCBvZiBhbm90aGVyIHZhcmlhYmxlLCBzYXkgaW50ZWxsaWdlbmNlLgoKTGV0J3MgYWRkIGFuIGludGVyYWN0aW9uIHRlcm06CgokeT3Osl8wICvOsl8xeF8xICvOsl8yeF8yICvOsl8zeF8xeF8yICt1JAoKSG9sZGluZyAkeF8yJCAoYW5kIHUpIGZpeGVkLCB0aGUgcGFydGlhbCBlZmZlY3Qgb2YgJHhfMSQgb24geSBpczoKClxiZWdpbntlcXVhdGlvbn0KXGZyYWN7XERlbHRhIHl9e1xEZWx0YSB4XzF9ID1cYmV0YV8xICsgXGJldGFfM3hfMgpcZW5ke2VxdWF0aW9ufQoKc28gdGhhdCB0aGUgZWZmZWN0IG9mICR4XzEkIGRlcGVuZHMgb24gJHhfMiQgdW5sZXNzICRcYmV0YV8zID0gMCQ6ClxiZWdpbntlcXVhdGlvbn0KXGZyYWN7XERlbHRhIHl9e1xEZWx0YSB4XzJ9ID1cYmV0YV8yICsgXGJldGFfM3hfMQpcZW5ke2VxdWF0aW9ufQoKVGhlIG51bGwgaHlwb3RoZXNpcyAkSF8wIDogzrJfMyA9IDAkIGlzIHRoZSBzYW1lIGFzIHNheWluZyB0aGUgcGFydGlhbCBlZmZlY3RzIGFyZSBjb25zdGFudC4gSXQgc2hvdWxkIGJlIHRlc3RlZC4gSWYgaXQgY2Fubm90IGJlIHJlamVjdGVkIGF0IGEgc21hbGwgc2lnbmlmaWNhbmNlIGxldmVsIChzbWFsbGVyIHRoYW4gNSUpLCBpdCBpcyBub3Qgd29ydGggY29tcGxpY2F0aW5nIHRoZSBtb2RlbC4KCkl0IGlzIGVhc3kgdG8gZ2V0IGNvbmZ1c2VkIGluIG1vZGVscyB3aXRoIGludGVyYWN0aW9ucy4gRnJvbQoKXGJlZ2lue2VxdWF0aW9ufQpcZnJhY3tcRGVsdGEgeX17XERlbHRhIHhfMX0gPVxiZXRhXzEgKyBcYmV0YV8zeF8yClxlbmR7ZXF1YXRpb259Cgp3ZSBzZWUgdGhhdCAkzrJfMSQgaXMgbm93IHRoZSBQRSBvZiAkeF8xJCBvbiB5IHdoZW4gJHhfMiQgPTAuIEJ1dCAkeF8yID0wJCBtYXkgYmUgdmVyeSBmYXIgZnJvbSBhIGxlZ2l0aW1hdGUsIG9yIGF0IGxlYXN0IGludGVyZXN0aW5nLCBwYXJ0IG9mIHRoZSBwb3B1bGF0aW9uLiBBIHNpbWlsYXIgY29tbWVudCBob2xkcyBmb3IgJM6yXzEkLgoKVHdvIGludGVyZXN0aW5nIHBhcmFtZXRlcnMgYXJlIHRoZSBQRXMgZXZhbHVhdGVkIGF0IHRoZSBtZWFuIG9mIHRoZSBvdGhlciB2YXJpYWJsZToKClxiZWdpbntlcXVhdGlvbn0KXGdhbW1hXzEgPSBcYmV0YV8xICtcYmV0YV8zIFxtdV8yClxlbmR7ZXF1YXRpb259CgpcYmVnaW57ZXF1YXRpb259ClxnYW1tYV8yID0gXGJldGFfMiArXGJldGFfMyBcbXVfMQpcZW5ke2VxdWF0aW9ufQoKV2Ugd2lsbCBlc3RpbWF0ZSB0aGVzZSBhczoKClxiZWdpbntlcXVhdGlvbn0KXGhhdHtcZ2FtbWFfMX0gPSBcaGF0e1xiZXRhXzF9ICtcaGF0e1xiZXRhXzN9IFxiYXJ7eH1fMgpcZW5ke2VxdWF0aW9ufQoKXGJlZ2lue2VxdWF0aW9ufQpcaGF0e1xnYW1tYV8yfSA9IFxoYXR7XGJldGFfMn0gK1xoYXR7XGJldGFfM30gXGJhcnt4fV8xClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkXGJhcnt4fV8yJCBhbmQgJFxiYXJ7eH1fMSQgYXJlIHRoZSBzYW1wbGUgYXZlcmFnZXMgYW5kIHRoZSAkXGhhdHtcYmV0YV8yfSQgYXJlIHRoZSBPTFMgZXN0aW1hdGVzLgoKSXQgaXMgb2Z0ZW4gZWFzaWVyIHRvIGxldCBhIHJlZ3Jlc3Npb24gY29tcHV0ZSAkXGhhdHtcZ2FtbWFfMX0kIGFuZCAkXGhhdHtcZ2FtbWFfMn0kLCBhbmQgdG8gZ2V0IGFwcHJvcHJpYXRlIHN0YW5kYXJkIGVycm9ycy4gV2UgY2FuIHdyaXRlIGluIHRoZSBwb3B1bGF0aW9uClxiZWdpbntlcXVhdGlvbn0KeSA9IFxhbHBoYV8wICsgXGdhbW1hXzEgeF8xICsgIFxnYW1tYV8yIHhfMiArIFxiZXRhXzMoeF8xIC0gXG11XzEpICh4XzIgLSBcbXVfMikgK3UKXGVuZHtlcXVhdGlvbn0KCkluIG90aGVyIHdvcmRzLCB3ZSBzdWJ0cmFjdCB0aGUgbWVhbnMgYmVmb3JlIGNyZWF0aW5nIHRoZSBpbnRlcmFjdGlvbnMuClRoZSByZWdyZXNzaW9uIHdlIHJ1biBpcwoKJHlfaSQgb24gJHhfe2kxfSQsICQoeF97aTF9IC0gXGJhcnt4XzF9KSh4X3tpMn0gLSBcYmFye3hfMn0pLCBpICA9IDEsIFxkb3RzLG4kCgoKVGhlIGludGVyY2VwdCBjaGFuZ2VzLCB0b28sIGJ1dCB0aGlzIGlzIG5vdCBpbXBvcnRhbnQuIFRoZSBjb2VmZmljaWVudCBvbiB0aGUgaW50ZXJhY3Rpb24gZG9lcyBub3QgY2hhbmdlLgoKTGV0J3Mgc2VlIGl0OgoKRmlyc3QgbW9kZWwgdGhlIGludGVyYWN0aW9uIGlzIGVkdWMqSVEKCmBgYHtyfQp3YWdlX2xpbiA8LSBsbShsb2cod2FnZSkgfmVkdWMgKyBJUSAgLCBkYXRhID0gd2FnZTIpCnN1bW1hcnkod2FnZV9saW4pCgp3YWdlX2ludCA8LSBsbShsb2cod2FnZSkgfmVkdWMgKyBJUSArIGVkdWMqSVEgLCBkYXRhID0gd2FnZTIpCnN1bW1hcnkod2FnZV9pbnQpCmBgYApOb3csIGxldCdzIHNlZSB0aGUgcmVncmVzc2lvbiB3aXRoIG1lYW4gYWRqdXN0ZWQgdmFsdWVzLgoKYGBge3IsIHJlc3VsdHM9J2FzaXMnfQoKI0dlbmVyYXRlIG1lYW4gdmFsdWVzIGZvciBlYWNoIHZhcmlhYmxlCmRhdGEod2FnZTIpCgptZWFuX2VkdWMgPSBtZWFuKHdhZ2UyJGVkdWMpCgpzdW1tYXJ5KHdhZ2UyJElRKQptZWFuX2lxID0gbWVhbih3YWdlMiRJUSkKCiNjcmVhdGUgYSBuZXcgdmFyaWFibGUgdXNpbmcgbXV0YXRlIHRoYXQgaXMgdGhlIG1lYW4gYWRqdXN0ZWQgdmFsdWUgZm9yIGVkdWMgYW5kIElRCndhZ2UyIDwtbXV0YXRlKHdhZ2UyLCBtZWFuX2VkdWNfYWRqICA9IGVkdWMtbWVhbl9lZHVjLCBtZWFuX2lxX2FkaiA9IElRLW1lYW5faXEpCgojcnVuIHRoZSByZWdyZXNzaW9uIHdpdGggdGhlIG1lYW4gYWRqdXN0ZWQgcmVncmVzc2lvbgp3YWdlX2ludF9tZWFuYWRqIDwtIGxtKGxvZyh3YWdlKSB+ZWR1YyArIElRICsgbWVhbl9lZHVjX2FkaiptZWFuX2lxX2FkaiAgLCBkYXRhID0gd2FnZTIpCgoKbGlicmFyeSgic3RhcmdhemVyIikKc3RhcmdhemVyKHdhZ2VfaW50X21lYW5hZGosIHdhZ2VfaW50LCB0eXBlID0gImh0bWwiLCAKICAgICAgICAgIHJlc3VsdHMgPSAnYXNpcycsbWVzc2FnZSA9IEZBTFNFLCBlY2hvID0gRkFMU0UsIG5vdGVzLmFwcGVuZCA9IEZBTFNFLCBoZWFkZXIgPSBGQUxTRSwgc2luZ2xlLnJvdyA9IFRSVUUpCgoKYGBgCgpZb3UgY2FuIHNlZSB0aGF0IHRoZSBpbnRlcmFjdGlvbiB0ZXJtIGlzIHRoZSBzYW1lIGJldHdlZW4gdGhlIG1lYW4gY2VudGVyZWQgYW5kIHVuY2VudGVyZWQgcmVncmVzc2lvbnMuCgpUaGUgaW50ZXJhY3Rpb24gdGVybSBpcyBub3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gQW5kIHNpbWlsYXJseSwgd2UgY2FuIHNlZSB0aGF0IHdoZW4gY2VudGVyaW5nIGhhcyBiZWVuIGRvbmUsIHRoZXNlIGVzdGltYXRlcyBhcmUgbXVjaCBjbG9zZXIgdG8gdGhlIHJlZ3Jlc3Npb24gd2l0aG91dCBpbnRlcmFjdGlvbnMgKDAuMDM5MTE5OSwgIDAuMDA1ODYzMSBjb21wYXJlZCB0byAgMC4wMzg2MTA0LCAwLjAwNTkwNTIgKQoKVGhlIHBvc2l0aXZlIGNvZWZmaWNpZW50IG9uIHRoZSBpbnRlcmFjdGlvbiBtZWFucyB0aGF0IHRoZSByZXR1cm4gdG8gZWR1Y2F0aW9uIGlzIGhpZ2hlciBmb3IgcGVvcGxlIHdpdGggaGlnaGVyIGFiaWxpdHkuCgpUaGUgZXN0aW1hdGVkIHBhcnRpYWwgZWZmZWN0IG9mIGVkdWMgaXMgCiQwLjAzODYrMC4wMDAxKklRJApJZiBzb21lb25lIGhhcyBhbiBJUSB0aGF0IGlzIDEwIGFib3ZlIHRoZSBtZWFuLCB0aGUgcmV0dXJuIHRvIGVkdWNhdGlvbiBpczoKJDAuMDM4NiswLjAwMDEoMTAtMTAxLjI4KSA9IC4wMjk0JCBvciAyLjk0JQoKSWYgc29tZW9uZSBoYXMgYW4gSVEgdGhhdCBpcyAxMCBiZWxvdyB0aGUgbWVhbiwgdGhlIHJldHVybiB0byBlZHVjYXRpb24gaXM6CiQwLjAzODYrMC4wMDAxKC0xMC0xMDEuMjgpID0gLjAyNzQkIG9yIDIuNzQlCgpJZiB3ZSBjYW4gYmVsaWV2ZSB0aGVzZSBlc3RpbWF0ZXMsIHNjaG9vbGluZyBpcyB3b3J0aCBtb3JlIGZvciB0aG9zZSB3aXRoIGhpZ2hlciBpbnRlbGxpZ2VuY2UuCgojIyBEdW1teSBWYXJpYWJsZXMKCkR1bW15IHZhcmlhYmxlcyBhcmUgZXNzZW50aWFsbHksIGRpZmZlcmVuY2VzIGluIG1lYW5zIChhbmQgdGhpcyB3aWxsIGJlIFZFUlkgaW1wb3J0YW50IGZvciBEaWZmLURpZmYpIHJlZ3Jlc3Npb25zLgoKU2F5LCB3ZSBhcmUgaW50ZXJlc3RlZCBpbiB0aGUgZ2VuZGVyIHdhZ2UgZ2FwLCBhbmQgd2UgZXN0aW1hdGUgYSBzaW1wbGUgcmVncmVzc2lvbjoKClxiZWdpbntlcXVhdGlvbn0Kd2FnZSA9IFxiZXRhXzAgK1xnYW1tYV8wZmVtYWxlICt1ClxlbmR7ZXF1YXRpb259CgpXaGVyZSAkRSh1fGZlbWFsZSA9IDEpJCBhbmQgdGhlcmVmb3JlLAoKXGJlZ2lue2VxdWF0aW9ufQpFKHdhZ2V8ZmVtYWxlKSA9IFxiZXRhXzAgKyBcZ2FtbWFfMCBmZW1hbGUKXGVuZHtlcXVhdGlvbn0KClRoZXJlIGFyZSBvbmx5IHR3byB2YWx1ZXMgZm9yIGZlbWFsZSwgMCBhbmQgMS4KClxiZWdpbntlcXVhdGlvbn0KRSh3YWdlfGZlbWFsZSA9IDApID0gIFxiZXRhXzAgClxlbmR7ZXF1YXRpb259CgpcYmVnaW57ZXF1YXRpb259CkUod2FnZXxmZW1hbGUgPSAxKSA9IFxiZXRhXzAgKyBcZ2FtbWFfMCBmZW1hbGUKXGVuZHtlcXVhdGlvbn0KCldlIGNhbiB0aGVuIHdyaXRlLAoKXGJlZ2lue2VxdWF0aW9ufQpcZ2FtbWFfMCA9IEUod2FnZXxmZW1hbGUgPSAxKSAtIEUod2FnZXxmZW1hbGUgPSAwKQpcZW5ke2VxdWF0aW9ufQoKQW5kIHRoYXQncyBqdXN0IHRoZSBkaWZmZXJlbmNlIGluIHdhZ2UgYmV0d2VlbiB3b21lbiBhbmQgbWVuLgoKU28gJFxnYW1tYV8wJCBpcyBub3QgYSBzbG9wZS4gSXQncyBqdXN0IGEgZGlmZmVyZW5jZSBpbiBhdmVyYWdlIG91dGNvbWVzIGJldHdlZW4gdHdvIGdyb3Vwcy4KClRoZSBwb3B1bGF0aW9uIHJlbGF0aW9uc2hpcCBpcyBtaW1pY2tlZCBpbiB0aGUgc2ltcGxlIHJlZ3Jlc3Npb24gZXN0aW1hdGVzLgoKXGJlZ2lue2VxdWF0aW9ufQpcaGF0e1xiZXRhXzB9PSBcYmFye3dhZ2VfbX0KXGVuZHtlcXVhdGlvbn0KXGJlZ2lue2VxdWF0aW9ufQpcaGF0e1xiZXRhXzB9ICsgXGhhdHtcZ2FtbWFfMH09IFxiYXJ7d2FnZV9mfQpcZW5ke2VxdWF0aW9ufQpcYmVnaW57ZXF1YXRpb259ClxoYXR7XGdhbW1hXzB9PSBcYmFye3dhZ2VfZn0tXGJhcnt3YWdlX219ClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkXGJhcnt3YWdlX219JCBpcyB0aGUgYXZlcmFnZSB3YWdlIGZvciBtZW4gaW4gdGhlIHNhbXBsZSBhbmQgJFxiYXJ7d2FnZV9mfSQgaXMgdGhlIGF2ZXJhZ2Ugd2FnZSBmb3Igd29tZW4gaW4gdGhlIHNhbXBsZS4gCgpgYGB7cn0KZGF0YSh3YWdlMSkKCnN1bW1hcnkobG0od2FnZSB+IGZlbWFsZSwgZGF0YSA9IHdhZ2UxKSkKYGBgClRoZSBlc3RpbWF0ZWQgZWZmZWN0IGlzIGxhcmdlLCB3b21lbiBlYXJuIGFib3V0ICQyLjUgbGVzcyB0aGFuIG1lbi4KClRoZSBzaW1wbGUgcmVncmVzc2lvbiBpcyBhIGNvbXBhcmlzb24gb2YgbWVhbnMuIFdoZXJlIHdlIGFyZSB0ZXN0aW5nCgokSF8wOiBcbXVfZiA9IFxtdV9tJAoKd2hlcmUgzrxmIGlzIHRoZSBwb3B1bGF0aW9uIGF2ZXJhZ2Ugd2FnZSBmb3Igd29tZW4gYW5kIM68bSBpcyB0aGUgcG9wdWxhdGlvbiBhdmVyYWdlIHdhZ2UgZm9yIG1lbi4gVGhlIHQgc3RhdGlzdGljIGFuZCBjb25maWRlbmNlIGludGVydmFsIGFyZSBkaXJlY3RseSByZXBvcnRlZC4KCldlIGNhbiBzZWUgdGhlIHZhbHVlIGlzIDguMjc5IGFuZCBzdHJvbmdseSByZWplY3QgdGhlIG51bGwuCgpUaGUgZXN0aW1hdGUgJFxoYXR7XGdhbW1hXzB9ID0g4oiSMi41JCBkb2VzIG5vdCBjb250cm9sIGZvciBmYWN0b3JzIHRoYXQgc2hvdWxkIGFmZmVjdCB3YWdlLCBzdWNoIGFzIHdvcmtmb3JjZSBleHBlcmllbmNlIGFuZCBzY2hvb2xpbmcuIElmIHdvbWVuIGhhdmUsIG9uIGF2ZXJhZ2UsIGxlc3MgZXhwZXJpZW5jZSBhbmQgbGVzcyBjb2xsZWdlLCB0aGF0IGNvdWxkIGV4cGxhaW4gdGhlIGRpZmZlcmVuY2UgaW4gYXZlcmFnZSB3YWdlcy4KCklmIHdlIGp1c3QgY29udHJvbCBmb3IgZXhwZXJpZW5jZSwgdGhlIG1vZGVsIHdyaXR0ZW4gaW4gZXhwZWN0ZWQgdmFsdWUgZm9ybSBpcwokRSh3YWdlfGZlbWFsZSxleHBlcik9zrJfMCArzrRfMGZlbWFsZSvOsl8xZXhwZXIkCgp3aGVyZSBub3cgJM60XzAkIG1lYXN1cmVzIHRoZSBnZW5kZXIgZGlmZmVyZW5jZSB3aGVuIHdlIGhvbGQgZml4ZWQgZXhwZXIuCgpBbm90aGVyIHdheSB0byB3cml0ZSAkzrRfMCQ6ClxiZWdpbntlcXVhdGlvbn0KzrRfMCA9RSh3YWdlfGZlbWFsZSxleHBlcl8wKeKIkkUod2FnZXxtYWxlLGV4cGVyXzApClxlbmR7ZXF1YXRpb259CndoZXJlICRleHBlcl8wJCBpcyBhbnkgbGV2ZWwgb2YgZXhwZXJpZW5jZSB0aGF0IGlzIHRoZSBzYW1lIGZvciB0aGUgd29tYW4gYW5kIG1hbi4KCmBgYHtyfQpkYXRhKHdhZ2UxKQoKc3VtbWFyeShsbSh3YWdlIH4gZmVtYWxlK2V4cGVyLCBkYXRhID0gd2FnZTEpKQpgYGAKClRoZXJlIGlzIHN0aWxsIGEgZGlmZmVyZW5jZSBvZiBhYm91dCAkMi4yNywgd2hpY2ggaXMgc21hbGxlciB0aGFuIHdoZW4gZXhwZXIgaXMgbm90IGNvbnRyb2xsZWQgZm9yLCBidXQgc3RpbGwgdmVyeSBsYXJnZSBhbmQgdmVyeSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LgoKVGhpcyBtb2RlbCBpbXBvc2VzIGEgY29tbW9uIHNsb3BlIG9uIGV4cGVyIGZvciBtZW4gYW5kIHdvbWVuICguNTApICAtIE9ubHkgdGhlIGludGVyY2VwdHMgZGlmZmVyCgohW2ludGVyY2VwdCBkaWZmZXJdKHNsaWRlc18xMV8xLnBuZykKV2UgY2FuIGFkZCBhZGRpdGlvbmFsIGNvbnRyb2xzLCBhcyB3ZWxsLiAgCgpgYGB7cn0Kc3VtbWFyeShsbSh3YWdlIH4gZmVtYWxlK2VkdWMrZXhwZXIrbWFycmllZCwgZGF0YSA9IHdhZ2UxKSkKYGBgCgpMZXQncyBzYXkgeW91IGVzdGltYXRlOgoKXGJlZ2lue2VxdWF0aW9ufQp3YWdlID0gXGJldGFfMCArIFxiZXRhXzEgbWFsZQpcZW5ke2VxdWF0aW9ufQoKV2hhdCBpcyB0aGUgZXhwZWN0ZWQgc2lnbiAoZ2l2ZW4gdGhhdCB5b3Uga25vdyBpbmZvcm1hdGlvbiBmcm9tIHRoZSBwcmlvciByZWdyZXNzaW9uKT8KCgpOb3RlOiBhcyB5b3UgbWF5IHJlY2FsbCwgaWYgeW91IHB1dCBmZW1hbGUgYW5kIG1hbGUgaW50byB0aGUgc2FtZSByZWdyZXNzaW9uLCB5b3Ugd2lsbCBoYXZlIGEgZHVtbXkgdmFyaWFibGUgdHJhcC4KCiMjIyMgRHVtbXkgdmFyaWFibGVzIHdpdGggTXVsdGlwbGUgQ2F0ZWdvcmllcwoKU3VwcG9zZSBpbiB0aGUgd2FnZSBleGFtcGxlIHdlIGhhdmUgdHdvIHF1YWxpdGF0aXZlIHZhcmlhYmxlcywgZ2VuZGVyIGFuZCBtYXJpdGlhbCBzdGF0dXMuIENhbGwgdGhlc2UgZmVtYWxlIGFuZCBtYXJyaWVkLgoKV2UgY2FuIGRlZmluZSBmb3VyIGV4aGF1c3RpdmUgYW5kIG11dHVhbGx5IGV4Y2x1c2l2ZSBncm91cHMuIFRoZXNlIGFyZSBtYXJyaWVkIG1hbGVzIChtYXJybWFsZSksIG1hcnJpZWQgZmVtYWxlcyAobWFycmZlbSksIHNpbmdsZSBtYWxlcyAoc2luZ21hbGUpLCBhbmQgc2luZ2xlIGZlbWFsZXMgKHNpbmdmZW0pLgoKTm90ZSB0aGF0IHdlIGNhbiBkZWZpbmUgZWFjaCBvZiB0aGVzZSBkdW1teSB2YXJpYWJsZXMgaW4gdGVybXMgb2YgZmVtYWxlIGFuZCBtYXJyaWVkOgoKXGJlZ2lue2VxdWF0aW9ufQptYXJybWFsZSA9IG1hcnJpZWQgKDEtZmVtYWxlKQpcZW5ke2VxdWF0aW9ufQoKXGJlZ2lue2VxdWF0aW9ufQptYXJyZmVtID0gbWFycmllZCAqIGZlbWFsZQpcZW5ke2VxdWF0aW9ufQoKXGJlZ2lue2VxdWF0aW9ufQpzaW5nbWFsZSA9ICgxLW1hcnJpZWQpKDEtZmVtYWxlKQpcZW5ke2VxdWF0aW9ufQoKXGJlZ2lue2VxdWF0aW9ufQpzaW5nZmVtID0gKDEtbWFycmllZClmZW1hbGUKXGVuZHtlcXVhdGlvbn0KCldlIGNhbiBhbGxvdyBlYWNoIG9mIHRoZSBmb3VyIGdyb3VwcyB0byBoYXZlIGEgZGlmZmVyZW50IGludGVyY2VwdCBieSBjaG9vc2luZyBhIGJhc2UgZ3JvdXAgYW5kIHRoZW4gaW5jbHVkaW5nIGR1bW1pZXMgZm9yIHRoZSBvdGhlciB0aHJlZSBncm91cHMuIAoKU28sIGlmIHdlIGNob29zZSBzaW5nbGUgbWFsZXMgYXMgdGhlIGJhc2UgZ3JvdXAsIHdlIGluY2x1ZGUgbWFycm1hbGUsCm1hcnJmZW0sIGFuZCBzaW5nZmVtIGluIHRoZSByZWdyZXNzaW9uLiAKClRoZSBjb2VmZmljaWVudHMgb24gdGhlc2UgdmFyaWFiZWxzIGFyZSByZWxhdGl2ZSB0byBzaW5nbGUgbWVuLgoKV2l0aCBsd2FnZSBhcyB0aGUgZGVwZW5kZW50IHZhcmlhYmxlLCB3ZSBjYW4gZ2l2ZSB0aGVtIGEgcGVyY2VudGFnZSBjaGFuZ2UgaW50ZXJwcmV0YXRpb24uCgpgYGB7cn0Kd2FnZTEgPC1tdXRhdGUod2FnZTEsIG1hcnJtYWxlID0gbWFycmllZCooMS1mZW1hbGUpLCAgIG1hcnJmZW0gPSBtYXJyaWVkKmZlbWFsZSwgc2luZ21hbGUgPSAoMS1tYXJyaWVkKSooMS1mZW1hbGUpLCBzaW5nZmVtID0gKDEtbWFycmllZCkqZmVtYWxlKQoKc3VtbWFyeShsbShsb2cod2FnZSkgfiBtYXJybWFsZSArbWFycmZlbSArc2luZ2ZlbSArZWR1YyArc3RhdHM6OnBvbHkoZXhwZXIsMikgKyBzdGF0czo6cG9seSh0ZW51cmUsMiksIGRhdGEgPSB3YWdlMSkpCgpzdW1tYXJ5KGxtKGxvZyh3YWdlKSB+IGZlbWFsZSttYXJyaWVkKyBmZW1hbGUqbWFycmllZCArZWR1YyArc3RhdHM6OnBvbHkoZXhwZXIsMikgKyBzdGF0czo6cG9seSh0ZW51cmUsMiksIGRhdGEgPSB3YWdlMSkpCmBgYApXaGF0IGlmIHdlIHdhbnQgdG8gY29tcGFyZSBtYXJyaWVkIHdvbWVuIGFuZCBzaW5nbGUgd29tZW4/IAoKSnVzdCBwbHVnIGluIHRoZSBjb3JyZWN0IHNldCBvZiB6ZXJvcyBhbmQgb25lcy4Kc2xvcGUgZm9yIG1hcnJpZWQgd29tZW4gPSAuNjMg4oiSIC4xOTggKC40MzIpIHNsb3BlIGZvciBzaW5nbGUgd29tZW4gPSAuNjMg4oiSIC4xMSAoLjUyKSBkaWZmZXJlbmNlID0g4oiSLjE5OCDiiJIgKOKIki4xMTApID0g4oiSLjA4OApzbyBtYXJyaWVkIHdvbWVuIGVhcm4gYWJvdXQgOC44JSBsZXNzIHRoYW4gc2luZ2xlIHdvbWVuIChjb250cm9sbGluZyBmb3Igb3RoZXIgZmFjdG9ycykuCgpXZSBjYW5ub3QgdGVsbCBmcm9tIHRoZSBwcmV2aW91cyBvdXRwdXQgd2hldGhlciB0aGlzIGRpZmZlcmVuY2UgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCAoeW91IGNhbiBjYWxjdWxhdGUgdGhpcyBrbm93aW5nIHRoYXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gdmFyaWFuY2VzIGlzIHRoZSBzdW0gb2YgdGhlIHZhcmlhbmNlLCB0aHVzICRcc3FydHtzZV97bWFycmZlbX0gKyBzZV97c2luZ2ZlbX19JAoKTm8gbWF0dGVyIHdoaWNoIGdyb3VwIHdlIGNob29zZSBhcyB0aGUgYmFzZSBncm91cCwgd2UgaW5jbHVkZSBvbmx5IHRocmVlIG9mIHRoZSBmb3VyIGR1bW15IHZhcmlhYmxlcy4gSWYgd2UgaW5jbHVkZSBhbGwgZm91ciB3ZSBmYWxsIGludG8gdGhlIGR1bW15IHZhcmlhYmxlIHRyYXAuCgpJbmNpZGVudGFsbHksIGluIHRoaXMgZGF0YSBzZXQsIGdlbmRlciwgbWFycml0YWwgc3RhdHVzLCBlZHVjYXRpb24sIGV4cGVyaWVuY2UsIGFuZCB0ZW51cmUgZXhwbGFpbiBhYm91dCA0NSUgKHVzaW5nICRSXjIkKSBvZiB0aGUgdmFyaWF0aW9uIGluIGx3YWdlLgoKCiMjIyMgSW5jb3Jwb3JhdGluZyBvcmRpbmFsIHZhcmlhYmxlcwoKTGV0J3MgdGFrZSBhbiBleGFtcGxlIHVzaW5nIHRoZSBkYXRhc2V0IGJlYXV0eSB3aGljaCBpbmNsdWRlcyBhIHJhbmtpbmcgb2YgcGh5c2ljYWwgYXR0cmFjdGl2ZW5lc3Mgb2YgZWFjaCBtYW4gb3Igd29tYW4sIG9uIGEgc2NhbGUgb2YgMSB0byA1LCB3aXRoIDUgYmVpbmcg4oCcc3RyaWtpbmdseSBiZWF1dGlmdWwgb3IgaGFuZHNvbWUu4oCdIFRoaXMgaXMgYSBzdWJzZXQgb2YgdGhlIGRhdGEgdXNlZCBpbiBIYW1lcm1lc2ggYW5kIEJpZGRsZSAoMTk5NCwgQW1lcmljYW4gRWNvbm9taWMgUmV2aWV3KS4KCkFzIHdlIG1vdmUgdXAgdGhlIHNjYWxlIGZyb20gMSB0byA1LCB3aHkgc2hvdWxkIGEgb25lLXVuaXQgaW5jcmVhc2UgbWVhbiB0aGUgc2FtZSBhbW91bnQgb2Yg4oCcYmVhdXR54oCdPwoKVGhlIOKAnGxvb2tz4oCdIHZhcmlhYmxlIGlzIHdoYXQgd2UgY2FsbCBhbiBvcmRpbmFsIHZhcmlhYmxlOiB3ZSBrbm93IHRoYXQgdGhlIG9yZGVyIG9mIG91dGNvbWVzIGNvbnZleXMgaW5mb3JtYXRpb24gKDUgaXMgYmV0dGVyIHRoYW4gNCwgYW5kIDIgaXMgYmV0dGVyIHRoYW4gMSkgYnV0IHdlIGRvIG5vdCBrbm93IHRoYXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiA1IGFuZCA0IGlzIHRoZSBzYW1lIGFzIDIgYW5kIDEuCgpMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgZGF0YQoKYGBge3J9CmRhdGEoYmVhdXR5KQp0YWJsZShiZWF1dHkkbG9va3MpCmBgYAoKIFZlcnkgZmV3IHBlb3BsZSBhcmUgYXQgdGhlIGV4dHJlbWUgdmFsdWVzIDEgYW5kIDUgKGxlc3MgdGhhbiAxJSBlYWNoKS4gSXQgbWFrZXMgc2Vuc2UgdG8gY29tYmluZSBpbnRvIHRocmVlIGNhdGVnb3JpZXM6IGJlbG93IGF2ZXJhZ2UgKGJlbGF2ZyksIGF2ZXJhZ2UsIGFuZCBhYm92ZSBhdmVyYWdlIChhYnZhdmcpLgoKYGBge3J9CmxpYnJhcnkoamFuaXRvcikKYmVhdXR5IDwtIG11dGF0ZShiZWF1dHksIGJlbG93YXYgPSBpZl9lbHNlKGxvb2tzIDw9IDIsIDEsMCksIGFib3ZhdiA9aWZfZWxzZShsb29rcyA+PSA0LDEsMCkpCnRhYnlsKGJlYXV0eSRiZWxvd2F2LCBzaG93X25hID0gVFJVRSkKdGFieWwoYmVhdXR5JGFib3Zhdiwgc2hvd19uYSA9IFRSVUUpCmBgYAoxMi41JSBvZiBwZW9wbGUgYXJlICJiZWxvdyBhdmVyYWdlIiBhbmQgMzAuMyUgaGF2ZSBhYm92ZSBhdmVyYWdlIGxvb2tzIC0gZXZlcnlvbmUgZWxzZSBoYXMgImF2ZXJhZ2UgbG9va3MgKGxvb2tzID0zKQoKVGFrZSBhdmVyYWdlIGFzIHRoZSBiYXNlIGdyb3VwLgpgYGB7cn0Kc3VtbWFyeShsbShsd2FnZSB+YmVsb3dhdisgYWJvdmF2LCBkYXRhID0gYmVhdXR5KSkKYGBgCkNvbnRyb2xsaW5nIGZvciBubyBvdGhlciBmYWN0b3JzLCB0aG9zZSB3aXRoIGJlbG93IGF2ZXJhZ2UgbG9va3MgZWFybiBhYm91dCAyMC44JSBsZXNzIHRoYW4gdGhvc2Ugd2l0aCBhdmVyYWdlIGxvb2tzLiBUaGUgdCBzdGF0aXN0aWMgaXMgdmVyeSBzaWduaWZpY2FudCAocC0gdmFsdWUgaXMgc3VwZXIgbG93KS4KClRob3NlIHdpdGggYWJvdmUgYXZlcmFnZSBsb29rcyBhcmUgZXN0aW1hdGVkIHRvIGVhcm4gYWJvdXQgNC41JSBsZXNzIHRoYW4gdGhvc2Ugd2l0aCBhdmVyYWdlIGxvb2tzLCBidXQgdGhlIHAtdmFsdWUgaXMgLjI2NC4gU28gdGhlcmUgaXMgbGl0dGxlIGV2aWRlbmNlIHRoZSBlZmZlY3QgaXMgZGlmZmVyZW50IGZyb20gemVyby4KCgpOb3cgY29udHJvbCBmb3Igc29tZSBvdGhlciBmYWN0b3JzLCBpbmNsdWRpbmcgZ2VuZGVyIGFuZCBlZHVjYXRpb24uCgpgYGB7cn0Kc3VtbWFyeShsbShsd2FnZSB+YmVsb3dhdisgYWJvdmF2K2VkdWMrc3RhdHM6OnBvbHkoZXhwZXIsMiksIGRhdGEgPSBiZWF1dHkpKQpgYGAKClRoZSBlZmZlY3Qgb2YgaGF2aW5nIGJlbG93IGF2ZXJhZ2UgbG9va3MgaXMgbm93IGFib3V0IDE4JSBsb3dlciBzYWxhcnkgKG9uIGF2ZXJhZ2UpLiBBYm92ZSBhdmVyYWdlIGxvb2tzIGlzIHN0aWxsIHN0YXRpc3RpY2FsbHkgaW5zaWduaWZpY2FudCBhbmQgZ2V0cyBzbWFsbGVyIGluIG1hZ25pdHVkZS4KCkdvb2QgcHJhY3RpY2UgdG8gbG9vayBhdCBhbGwgY29lZmZpY2llbnRzIHRvIHNlZSBpZiB0aGUgc2lnbnMgYW5kIG1hZ25pdHVkZXMgbWFrZSBzZW5zZS4gVGhleSBkbywgYWx0aG91Z2ggdGhlIHByZW1pdW0gZm9yIG1hbGVzIGlzIHZlcnkgbGFyZ2UuCgpgYGB7cn0Kc3VtbWFyeShsbShsd2FnZSB+IGxvb2tzK2VkdWMrc3RhdHM6OnBvbHkoZXhwZXIsMiksIGRhdGEgPSBiZWF1dHkpKQpgYGAKClB1dHRpbmcgaW4gdGhlIHZhcmlhYmxlIGxvb2tzIG1lYW5zIHRoYXQgYmV0dGVyIGxvb2tzIGFsd2F5cyBoYXMgdG8gaGF2ZSBhIHBvc2l0aXZlIGVmZmVjdC4gSXQgaXMgbm90IGFzIHNpZ25pZmljYW50IGFuZCBmaXRzIHNsaWdodGx5IGxlc3Mgd2VsbCAodXNlIGFkanVzdGVkIFIyICkuCgpgYGB7cn0Kc2QoYmVhdXR5JGxvb2tzKQpgYGAKCkEgb25lIHN0YW5kYXJkIGRldmlhdGlvbiBpbmNyZWFzZSBpbiBsb29rcyBpbmNyZWFzZXMgcHJlZGljdGVkIGx3YWdlIGJ5IC4wNjIoLjY4KSA9IC4wNDIsIG9yIHByZWRpY3RlZCB3YWdlIGJ5IGFib3V0IDQuMiUuCgpMZXQncyBzZWUgd2hhdCBoYXBwZW5zIGlmIHdlIGxvb2sgYXQgdGhlIGVmZmVjdHMganVzdCBmb3Igd29tZW4KYGBge3J9CnN1bW1hcnkobG0obHdhZ2UgfiBiZWxvd2F2KyBhYm92YXYrZWR1YytzdGF0czo6cG9seShleHBlciwyKSwgZGF0YT1zdWJzZXQoYmVhdXR5LGZlbWFsZSA9PTEpKSkKYGBgCgpFcXVhdGlvbiBmb3Igd29tZW4gb25seSBpcyBzdWdnZXN0aXZlIG9mIGEgcG9zaXRpdmUgZWZmZWN0IG9mIGFib3ZlIGF2ZXJhZ2UgbG9va3MsIGJ1dCB0aGUgZXN0aW1hdGVzIGFyZSBpbXByZWNpc2Ugd2l0aCBvbmx5IDIxMyBvYnNlcnZhdGlvbnMuIEluIGZhY3QsIGJlbGF2ZyBpcyBubyBsb25nZXIgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBldmVuIHRob3VnaCBpdHMgY29lZmZpY2llbnQgaXMgc3RpbGwgcHJldHR5IGxhcmdlLCDiiJIuMTI1LgoKT25lIHNob3J0Y29taW5nIGluIHRoZSBwcmV2aW91cyBhbmFseXNpcyBpcyB0aGF0IGl0IGlnbm9yZXMgb2NjdXBhdGlvbi4gTWF5YmUgd2Ugc2hvdWxkIGFsbG93IHBlb3BsZSB0byBzb3J0IGludG8gb2NjdXBhdGlvbiAocGVyaGFwcyBwYXJ0bHkgYmFzZWQgb24gbG9va3MpIGFuZCBzZWUgaWYgdGhlcmUgaXMgYSDigJxsb29rcyBwcmVtaXVt4oCdIGluIGEgZ2l2ZW4gb2NjdXBhdGlvbi4gQmlkZGxlIGFuZCBIYW1lcm1lc2ggKDE5OTgsIEpvdXJuYWwgb2YgTGFib3IgRWNvbm9taWNzKSBzdHVkeSBsYXd5ZXJz4oCZIGxvb2tzIGFuZCBlYXJuaW5ncyBhbmQgZmluZCBzaW1pbGFyIHJlc3VsdHMuCgpSZWNlbnRseSwgYSBwYXBlciBbZm91bmRdKGh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3MvajQzb2t1b2FrdnNtMzZoL1ByZXR0eTIwMjFKYW4yOS5wZGY/ZGw9MCkgdGhhdCBiZXR0ZXIgbG9va2luZyBlY29ub21pc3RzIGFyZSBjaXRlZCBtb3JlIGZyZXF1ZW50bHkgYW5kIGFyZSBtb3JlIGxpa2VseSB0byBiZSBwbGFjZWQgaW4gaGlnaGVyIHJhbmtpbmcgc2Nob29scy4gCgpWYXJpYWJsZXMgc3VjaCBhcyBjcmVkaXQgcmF0aW5ncywgb3IgYW55IHZhcmlhYmxlcyBhc2tlZCBvbiBhIHNjYWxlLCBhcmUgb3JkZXJlZCB2YXJpYWJsZXMuIEZvciBleGFtcGxlLCBzb21lb25lIG1heSBiZSBhc3NpZ25lZCBhIGNyZWRpdCByYXRpbmcgb24gYSBzY2FsZSBmcm9tIDEgdG8gNywgb3Igc29tZW9uZSBtYXkgYmUgYXNrZWQgdG8gcmF0ZSB0aGVpciDigJxoYXBwaW5lc3PigJ0gb24gYSBzY2FsZSBvZiAxIHRvIDUuCgojIyBJbnRlcmFjdGlvbnMgd2l0aCBEdW1teSBWYXJpYWJsZXMKQ29uc2lkZXIgYWdhaW4gdGhlIGx3YWdlIGVxdWF0aW9uIHdpdGggZ2VuZGVyIGFuZCBtYXJpdGFsIHN0YXR1cywgYWxsb3dpbmcgZm9yIHRoZSBmb3VyIGRpZmZlcmVudCBncm91cHMuIFdlIGNhbiBhY2hpZXZlIHRoZSBzYW1lIHRoaW5nIGJ5IHVzaW5nIGFuIGludGVyYWN0aW9uIGJldHdlZW4gZmVtYWxlIGFuZCBtYXJyaWVkLgoKSWYgd2UgcmVncmVzcyBsd2FnZSBvbiBmZW1hbGUsIG1hcnJpZWQsIGZlbWFsZSAqIG1hcnJpZWQgYW5kIHRoZSBlZHVjYXRpb24sIGV4cGVyaWVuY2UsIGFuZCB0ZW51cmUgdmFyaWFibGVzLCB3ZSBnZXQ6CgpgYGB7cn0Kc3VtbWFyeShsbShsb2cod2FnZSkgfiBmZW1hbGUrbWFycmllZCArZmVtYWxlKm1hcnJpZWQsIGRhdGEgPSB3YWdlMSkpCmBgYAoKCkp1c3QgcGx1ZyBpbiB0aGUgY29ycmVjdCBjb21iaW5hdGlvbiBvZiB6ZXJvcyBhbmQgb25lcyB0byBvYnRhaW4gZGlmZmVyZW5jZXMgYW1vbmcgdGhlIGdyb3Vwcy4gVGhlIGludGVyY2VwdCBjb3JyZXNwb25kcyB0byBmZW1hbGUgPSAwLCBtYXJyaWVkID0gMCwgc28gaXQgaXMgc3RpbGwgZm9yIHNpbmdsZSBtZW4uIEZvciBzaW5nbGUgd29tZW4sIGZlbWFsZSA9IDEsIG1hcnJpZWQgPSAwLCBhbmQgbWFycmllZCBtZW4gbWFycmllZCA9IDEsIGFuZCBmb3IgbWFycmllZCB3b21lbiBmZW1hbGUgPTEsIG1hcnJpZWQgPTEsIGZlbWFsZSptYXJyaWVkID0gMSAoLTYuMjI2KQoKCk9uZSBhZHZhbnRhZ2Ugb2YgdGhlIGVxdWF0aW9uIHdpdGggdGhlIGludGVyYWN0aW9uIGlzIHRoYXQgaXQgYWxsb3dzIHVzIHRvIHJlYWQgb2ZmIHRoZSBkaWZmZXJlbmNlIGluIG1hcnJpYWdlIHByZW1pdW0gYmV0d2VlbiB3b21lbiBhbmQgbWVuLiBGb3IgbWVuLCB0aGUgcHJlbWl1bSBpcyB0aGUgY29lZmZpY2llbnQgb24gbWFycmllZCwgIDIuODE1LiBUaGUgZGlmZmVyZW5jZSBpbiB0aGUgbWFycmlhZ2UgcHJlbWl1bSBpcyAtMi44NjA3ICwgYW5kIHNvIHRoZSBtYXJyaWFnZSBwcmVtaXVtIGZvciB3b21lbiBpcyAyLjgxNSDiiJIgLTIuODYwNyA9IC0uMDQ1Ny4KCldlIGNhbiBpbnRlcmFjdCBkdW1teSB2YXJpYWJsZXMgd2l0aCBxdWFudGl0YXRpdmUgdmFyaWFibGVzIHRvIG9idGFpbiByZWdyZXNzaW9uIG1vZGVscyB3aXRoIGRpZmZlcmVudCBzbG9wZXMsIGFzIHdlbGwgYXMgZGlmZmVyZW50IGludGVyY2VwdHMuCgpSZWNhbGwgdGhhdCBpbiB0aGUgbW9kZWwKJGx3YWdlID0gzrJfMCArIM60XzBmZW1hbGUgKyDOsl8xZXhwZXIgKyB1LCQKdGhlIGludGVyY2VwdCBmb3IgbWVuIGlzICTOsl8wJCBhbmQgdGhhdCBmb3Igd29tZW4gaXMgJM60XzAkLiBUaGUgc2xvcGUsICRcYmV0YV8xJDEsIGlzIGNvbW1vbiBhY3Jvc3MgbWVuIGFuZCB3b21lbi4KCkhvdyBjYW4gd2UgYWxsb3cgdGhlIHJldHVybiB0byBleHBlcmllbmNlIOKAkyB0aGF0IGlzLCB0aGUgc2xvcGUgaW4gdGhlIGx3YWdlIGVxdWF0aW9uIOKAkyB0byBkaWZmZXIgYnkgZ2VuZGVyPwoKQW4gZXh0ZW5kZWQgbW9kZWwgaXMKJGx3YWdlID0gKM6yXzAgKyDOtF8wZmVtYWxlKSArICjOsl8xICsgzrRfMWZlbWFsZSkgwrcgZXhwZXIgK3UgJAoKIEZvciBtZW4sIGZlbWFsZSA9IDAuIEZvciB3b21lbiwgcGx1ZyBpbiBmZW1hbGUgPSAxLgoKfCAgIHwgSW50ZXJjZXB0IHwgICAgfAotLS0tLXwtLS0tLS0tLXwtLS0tLS0tfApNYWxlfCAgICRcYmV0YV8wJCAgICAgICAgICAgIHwgICAgICRcYmV0YV8xJCB8CkZlbWFsZXwgJFxiZXRhXzAgKyBcZ2FtbWFfMCQgfCAkXGJldGFfMSArIFxnYW1tYV8xJCB8CkRpZmYoRmVtYWxlLU1hbGUpIHwgICRcZ2FtbWFfMCQgIHwgJFxnYW1tYV8xJCB8CgoKRm9yIG5vdywgd2UgdXNlIHRoZSBHcmVlayBsZXR0ZXIgZGVsdGEgdG8gZW1waGFzaXplIHRoYXQgJM60XzAkIGFuZCAkzrRfMSQgYXJlIGRpZmZlcmVuY2VzLgoKSG93IGNhbiB3ZSBlc3RpbWF0ZSB0aGUgZm91ciBwYXJhbWV0ZXJzLCAkzrJfMCzOsl8xLM60XzAkLCBhbmQkIFxnYW1tYV8xJD8gV3JpdGUgdGhlIG1vZGVsIGFzCiRsd2FnZSA9IM6yXzAgKyDOtF8wZmVtYWxlICsgzrJfMWV4cGVyICsgzrRfMWZlbWFsZSDCtyBleHBlciArIHUkCnNvIHdlIHNpbXBseSBhZGQgdGhlIGludGVyYWN0aW9uIHRlcm0gZmVtYWxlIMK3IGV4cGVyLgoKTm90ZSB0aGF0IGZlbWFsZSDCtyBleHBlciBpcyB6ZXJvIHdoZW5ldmVyIGZlbWFsZSA9IDAgKHRoYXQgaXMsIGZvciBhbGwKbWVuKS4KCkxldCdzIGFkZCBleHBlcmllbmNlCgpgYGB7cn0Kc3VtbWFyeShsbShsb2cod2FnZSkgfiBmZW1hbGUgKyBleHBlcisgZmVtYWxlKmV4cGVyLCBkYXRhID0gd2FnZTEpKQpgYGAKClRoZSBpbnRlcmNlcHQgZm9yIG1lbiBpcyAxLjY5IGFuZCB0aGUgc2xvcGUgaXMgMC4wMDQgKGFib3V0IC40MCUpIGZvciBlYWNoIHllYXIgb2YgZXhwZXJpZW5jZQpUaGUgaW50ZXJjZXB0IGZvciB3b21lbiBpcyAxLjY5IC0uMjkzICgxLjM5NykgYW5kIHRoZSBzbG9wZSBpcyAwLjAwNiAtMC4wMDU4ICAoYWJvdXQgLjAwMDIpIGZvciBlYWNoIHllYXIgb2YgZXhwZXJpZW5jZS4KVGhlIGludGVyYWN0aW9uIHRlcm0gaXMgbWFyZ2luYWxseSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHdpdGggYSBwLXZhbHVlIG9mIC4wNjM4CgpNdXN0IHVzZSBjYXJlIHRvIGludGVycHJldCB0aGUgY29lZmZpY2llbnQgb24gZmVtYWxlIHdoZW4gZmVtYWxlwrdleHBlciBpcyBpbiB0aGUgZXF1YXRpb24uIFRvIHNlZSB3aHksIGF0IGFueSBsZXZlbCBvZiBleHBlcmllbmNlLCB0aGUgcHJlZGljdGVkIGRpZmZlcmVuY2UgaW4gbHdhZ2UgYmV0d2VlbiBmZW1hbGVzIGFuZCBtYWxlcyBpcyAtLjI5MyArIC4wMDZleHBlcgoKVGhlcmVmb3JlLCB0aGUgY29lZmZpY2llbnQgb24gZmVtYWxlLCAtLjI5MywgaXMgdGhlIHByZWRpY3RlZCBkaWZmZXJlbmNlIGluIGx3YWdlIGJldHdlZW4gYSB3b21hbiBhbmQgbWFuIHdoZW4gZXhwZXIgPSAwLiBUaGlzIGlzIG5vdCBhbiBlc3BlY2lhbGx5IGludGVyZXN0aW5nIHN1YnNldCBvZiB0aGUgcG9wdWxhdGlvbi4gKE9ubHkgYWJvdXQgMS41JSBvZiB0aGUgc2FtcGxlIGhhcyBleHBlciBsZXNzIHRoYW4gMywgYW5kIG5vIG9uZSBjYW4gaGF2ZSB6ZXJvIHllYXJzLikKCgpNdXN0IHVzZSBjYXJlIHRvIGludGVycHJldCB0aGUgY29lZmZpY2llbnQgb24gZmVtYWxlIHdoZW4gZmVtYWxlwrdleHBlciBpcyBpbiB0aGUgZXF1YXRpb24uIFRvIHNlZSB3aHksIGF0IGFueSBsZXZlbCBvZiBleHBlcmllbmNlLCB0aGUgcHJlZGljdGVkIGRpZmZlcmVuY2UgaW4gbHdhZ2UgYmV0d2VlbiBmZW1hbGVzIGFuZCBtYWxlcyBpcwriiJIuNTE4ICsgLjAyMzRleHBlcgoKTW9yZSBpbnRlcmVzdGluZyBpcyB0aGUgZ2FwIGF0IGFyb3VuZCB0aGUgbWVhbiwgc2F5IGV4cGVyID0gMTA6CgoxLjY5IC0gMC4yOTMoMTApID0g4oiSMS4zNApvciBhYm91dCAxMzQlIGxlc3MgZm9yIHdvbWVuLgoKVGhlIGdhcCBuZXZlciBmdWxseSBjbG9zZXMuIFRoZSBsYXJnZXN0IGFtb3VudCBvZiBleHBlcmllbmNlIGluIHRoZSBzYW1wbGUgaXMgfjE0IHllYXJzLgoKV2UgY2FuIHVzZSB0aGUgc2FtZSBjZW50ZXJpbmcgc2NoZW1lIGFzIGJlZm9yZSB3aXRoIGludGVyYWN0aW9ucy4gUmUtIHBsYWNlIGZlbWFsZSDCtyBleHBlciB3aXRoIGZlbWFsZSDCtyAoZXhwZXIg4oiSIDEwKSBzbyB0aGF0IHRoZSBjb2VmZmljaWVudCBvbiBmZW1hbGViZWNvbWVzIHRoZSBkaWZmZXJlbmNlIGF0IDEwIHllYXJzIG9mIGV4cGVyaWVuY2UuCndoZXJlIDEwIGlzIGNsb3NlIHRvIHRoZSBtZWFuIHZhbHVlIG9mIGV4cGVyaWVuY2UgaW4gdGhlIHNhbXBsZS4KCmBgYHtyfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpYmJsZSkKd2FnZTEgPC0gbXV0YXRlKHdhZ2UxLCBmZW1leHBfMTAgPSBmZW1hbGUqKGV4cGVyLTEwKSkKCnN1bW1hcnkobG0obG9nKHdhZ2UpIH4gZmVtYWxlICsgZXhwZXIrIGZlbWV4cF8xMCwgZGF0YSA9IHdhZ2UxKSkKCmBgYAoKRG9uJ3QgbWluZCB0aGUgbnVtYmVycyBoZXJlLCBidXQgbGV0J3MgdmlzdWFsaXplIHdoYXQgaGVzZSBpbnRlcmFjdGlvbnMgbG9vayBsaWtlLgoKCiFbaW50ZXJjZXB0IGRpZmZlcl0oc2xpZGVzXzExXzIucG5nKQpMZXQncyBhZGQgYSB2YXJpYWJsZSBvZiBjb2xsZWdlIGFuZCBpbnRlcmFjdCBpdCB3aXRoIGdlbmRlcgoKYGBge3J9CndhZ2UxIDwtIG11dGF0ZSh3YWdlMSwgY29sbCA9IGlmX2Vsc2UoZWR1YyA+IDE1LDEsMCkpCgpmZW1hbGVfZWR1YyA8LWxtKGxvZyh3YWdlKSB+IGZlbWFsZSArIGV4cGVyKyBmZW1hbGUqZXhwZXIgK2NvbGwgK2ZlbWFsZSpjb2xsLCBkYXRhID0gd2FnZTEpCnN1bW1hcnkoZmVtYWxlX2VkdWMpCgpgYGAKCk5vdCBhbGwgb2YgdGhlIGludGVyYWN0aW9uIGFyZSBzaWduaWZpY2FudCwgYnV0IGxldCdzIHRlc3QgdG8gc2VlIGlmIHRoZXJlIGFyZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIG1hbGUgYW5kIGZlbWFsZSBlYXJuaW5ncy4KIAoKIyMjIyBDaG93IFRlc3QgCgogV2UgY2FuIHVzZSB0aGUgY2hvdyB0ZXN0IHRvIHRlc3QgZm9yIHRoZXNlIGRpZmZlcmVuY2VzLiBDaG93IHRlc3RzIGFyZSBrbm93biBmb3IgaWRlbnRpZnlpbmcgc3RydWN0dXJhbCBicmVha3MgLSBhbmQgdGhleSBoYXZlIG1hbnkgdXNlcy4gQnV0LCByZWFsbHksIGl0J3MganVzdCB0ZXN0aW5nIG9mIGVxdWFsaXR5IGJldHdlZW4gZ3JvdXBzLgogCiBUYWtlIHRoZSByZWdyZXNzaW9uIGVxdWF0aW9uOgogJGx3YWdlID0gzrJfMCArIM60XzBmZW1hbGUgKyDOsl8xZXhwZXIgKyDOtF8xZmVtYWxlIMK3IGV4cGVyICvOsl8yY29sbCArIM60XzJmZW1hbGUgwrcgY29sbCArIHUkCiAKIFRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGVyZSBpcyBubyBkaWZmZXJlbmNlIGluIGx3YWdlIGJldHdlZW4gbWVuIGFuZCB3b21lbiBhdCB0aGUgc2FtZSBsZXZlbHMgb2YgZXhwZXJpZW5jZSBhbmQgY29sbGVnZSBpczoKIAogJEhfMCA6zrRfMCA9MCzOtF8xID0wLM60XzIgPTAkCiAKVGhpcyBpcyBvbmUgdmVyc2lvbiBvZiB0aGUgQ2hvdyB0ZXN0IC0gd2hpY2ggdGVzdHMgZm9yIHRoZSBlcXVhbGl0eSBvZiByZWdyZXNzaW9uIGZ1bmN0aW9ucyBhY3Jvc3MgdHdvIGdyb3Vwcy4gV2UgdGVzdCBqb2ludCBzaWduaWZpY2FuY2Ugb2YgdGhlIGR1bW15IHZhcmlhYmxlIGRlZmluaW5nIHRoZSBncm91cHMgYXMgd2VsbCBhcyB0aGUgaW50ZXJhY3Rpb24gdGVybXMuCiAKIEluIHRoZSBnZW5lcmFsICRrJCB2YXJpYWJsZSBjYXNlLCB3ZSBjYW4gZGVmaW5lIGEgZHVtbXkgdmFyaWFibGUsICR3JCwgaW5kaWNhdGluZyB0aGUgdHdvIGdyb3Vwcy4gVGhlbiAKCgpcYmVnaW57ZXF1YXRpb259eSA9XGJldGEgX3swfSArXGJldGEgX3sxfSB4X3sxfSArXGJldGEgX3syfSB4X3syfSArXGxkb3RzICArXGJldGEgX3trfSB4X3trfSBcXAogK1xkZWx0YSBfezB9IHcgK1xkZWx0YSBfezF9IHcgXGNkb3QgeF97MX0gK1xkZWx0YSBfezJ9IHcgXGNkb3QgeF97Mn0gK1xsZG90cyAgK1xkZWx0YSBfe2t9IHcgXGNkb3QgeF97a30gK3UgXFwKSF97MH0gOlxkZWx0YSBfezB9ID0wICxcZGVsdGEgX3sxfSA9MCAsXGRlbHRhIF97Mn0gPTAgLFxsZG90cyAgLFxkZWx0YSBfe2t9ID0wXGVuZHtlcXVhdGlvbn1mb3IgJGsgKzEkIHJlc3RyaWN0aW9ucy4gCgpXZSBjYW4gdXNlIGEgc3RhbmRhcmQgJEYkIHRlc3Qgb2YgdGhlICRrICsxJCBleGNsdXNpb24gcmVzdHJpY3Rpb25zLgoKSXQgaXMgb2Z0ZW4gb2YgaW50ZXJlc3QgdG8gYWxsb3cgJFxkZWx0YSBfezB9IFxuZXEgMCQgYW5kIGp1c3QgdGVzdCBlcXVhbGl0eSBvZiB0aGUgc2xvcGVzOiAKClxiZWdpbntlcXVhdGlvbip9SF97MH0gOlxkZWx0YSBfezF9ID0wICxcZGVsdGEgX3syfSA9MCAsXGxkb3RzICAsXGRlbHRhIF97a30gPTAKXGVuZHtlcXVhdGlvbip9Tm93IHdlIGFyZSB0ZXN0aW5nICRrJCBwYXJhbWV0ZXJzIHVuZGVyICRIX3swfSQsIHNvIHdlIHVzZSB0aGUgJFxtYXRoY2Fse0Z9X3trICxuIC0yIChrICsxKX0kIGRpc3RyaWJ1dGlvbi4KCldlIGNhbiB1c2UgdGhlIHN1bSBvZiBzcXVhcmVkIHJlc2lkdWFscyB2ZXJzaW9uIG9mIHRoZSAkRiQgc3RhdGlzdGljLCB0b28uIFJhdGhlciB0aGFuIGNvbnN0cnVjdCBhbGwgb2YgdGhlIGludGVyYWN0aW9ucyBhbmQgcnVuIHRoZSByZWdyZXNzaW9ucyB3aXRoIGFuZCB3aXRob3V0IHRoZSBpbnRlcmFjdGlvbnMsIHdlCmNhbiBjb21wdXRlIHRocmVlIFNTUnMuIAoKMS4gUG9vbCB0aGUgZGF0YSBhbmQgZXN0aW1hdGUgYSBzaW5nbGUgcmVncmVzc2lvbi4gVGhpcyBpcyB0aGUgcmVzdHJpY3RlZCBtb2RlbCwgYW5kIHByb2R1Y2VzIHRoZSByZXN0cmljdGVkClNTUi4gQ2FsbCB0aGlzIHRoZSBcdGV4dGl0e3Bvb2xlZH0gU1NSLCAkUyBTIFJfe1B9JC4gCgoyLiBFc3RpbWF0ZSB0aGUgcmVncmVzc2lvbnMgb24gdGhlIHR3byBncm91cHMgKHNheSwgMSBhbmQgMikgc2VwYXJhdGVseS4gR2V0IHRoZSBTU1JzLCAkUyBTIFJfezF9JCBhbmQgJFMgUyBSX3syfSQuIFRoZSB1bnJlc3RyaWN0ZWQgU1NSIGlzICRTIFMgUl97MX0gK1MgUyBSX3syfSQgKGFuZCB0aGlzIGlzIHRoZSBzYW1lIGFzIHRoZSByZWdyZXNzaW9uIHRoYXQgaW5jbHVkZXMgdGhlIGZ1bGwgc2V0IG9mIGludGVyYWN0aW9ucykuCgogVGhlICRGJCBzdGF0aXN0aWMgaXMKXGJlZ2lue2VxdWF0aW9uKn1GID1cZnJhY3tbUyBTIFJfe1B9IC0oIFMgUyBSX3sxfSArUyBTIFJfezJ9KV0vKGsgKzEpfXsoUyBTIFJfezF9ICtTIFMgUl97Mn0pL1tuIC0yKGsgKzEpXX0KXGVuZHtlcXVhdGlvbip9YW5kLCB1bmRlciAkSF97MH0kLCBoYXMgdGhlICRcbWF0aGNhbHtGfV97ayArMSAsbiAtMiAoayBfMSl9JCBkaXN0cmlidXRpb24gdW5kZXIgJEhfezB9JC4gCgoKSWYgd2UgbGVhdmUgdGhlIGludGVyY2VwdHMgdW5yZXN0cmljdGVkIHVuZGVyICRIX3swfSQsIHRoZW4gJFMgUyBSX3tQfSQgaXMgb2J0YWluZWQgZnJvbSB0aGUgcG9vbGVkIHJlZ3Jlc3Npb24gYnV0IHdpdGggdGhlIGR1bW15IHZhcmlhYmxlIGFkZGVkLiBUaGUgJGsgKzEkIGluIHRoZSBudW1lcmF0b3IgYmVjb21lcyAkayQsIGFuZCB3ZSB1c2UgdGhlICRcbWF0aGNhbHtGfV97ayArMSAsbiAtMiAoa18xKX0kIGRpc3RyaWJ1dGlvbi4KCgpgYGB7ciwgcmVzdWx0cz0nYXNpcyd9CmxpYnJhcnkoc3RhcmdhemVyKQpsaWJyYXJ5KGNhcikKCiMgY3JlYXRlIGEgcmVncmVzc2lvbiBmb3Igb3VyIGZ1bGwgc2FtcGxlLCBtYWxlIGFuZCBmZW1hbGUgc2FtcGxlcwp3YWdlX2Z1bGwgPC1sbShsb2cod2FnZSkgfiBleHBlcisgY29sbCAsIGRhdGEgPSB3YWdlMSkKCiNjYWxjdWxhdGUgdGhlIHN1bSBvZiBzcXVhcmUgcmVzaWR1YWwKc3NwIDwtIHN1bShyZXNpZCh3YWdlX2Z1bGwpXjIpCgp3YWdlX2ZlbSA8LWxtKGxvZyh3YWdlKSB+IGV4cGVyKyBjb2xsICwgZGF0YSA9IHN1YnNldCh3YWdlMSwgZmVtYWxlID09MSkpCnNzMiA9IHN1bShyZXNpZCh3YWdlX2ZlbSleMikKCndhZ2VfbSA8LWxtKGxvZyh3YWdlKSB+IGV4cGVyKyBjb2xsICwgZGF0YSA9IHN1YnNldCh3YWdlMSwgZmVtYWxlID09MCkpCnNzMSA9IHN1bShyZXNpZCh3YWdlX20pXjIpCgojTm93LCB3ZSBjYW4gY2FsY3VsYXRlIG91ciBDaG93IHRlc3QKY2hvd3Rlc3QgPC0gKHNzcCAtIChzczErc3MyKSAvNCkgLyAoKHNzMStzczIpLyg1MjYtMiooNCkpKQpjaG93dGVzdAoKIyBub3cgYWRkIHRoZSBpbnRlcmNlcHQgc2hpZnQgKHJlY2FsbCB0aGF0J3Mgd2hhdCBhIGR1bW15IHZhcmlhYmxlIGlzLCBqdXN0IGFuIGludGVyY2VwdCBzaGlmdCwgbm90IGEgaW50ZXJjZXB0IEFORCBzbG9wZSBzaGlmdCB3aGljaCBpcyB3aGF0IGFuIGludGVyYWN0aW9uIGJldHdlZW4gYSBkdW1teSB2YXJpYWJsZSBhbmQgY29udGludW91cyB2YXJpYWJsZSBpcykKCnN1bW1hcnkod2FnZV9mX2ludCA8LWxtKGxvZyh3YWdlKSB+IHN0YXRzOjpwb2x5KGV4cGVyLDIpKyBjb2xsICtmZW1hbGUgLCBkYXRhID0gd2FnZTEpKQoKCnN0YXJnYXplcih3YWdlX2Z1bGwsIHdhZ2VfZmVtLCB3YWdlX20sIHdhZ2VfZl9pbnQsIHR5cGUgPSAiaHRtbCIsIAogICAgICAgICAgcmVzdWx0cyA9ICdhc2lzJyxtZXNzYWdlID0gRkFMU0UsIGVjaG8gPSBGQUxTRSwgbm90ZXMuYXBwZW5kID0gRkFMU0UsIGhlYWRlciA9IEZBTFNFLCBzaW5nbGUucm93ID0gVFJVRSkKCgpgYGAKIAogCgogQW4gYWR2YW50YWdlIG9mIHRoZSBhcHByb2FjaCBiYXNlZCBvbiBpbnRlcmFjdGlvbnMsIHRoYXQgd2Ugd2lsbCBzZWUgd2hlbiBkaXNjdXNzaW5nIGhldGVyb3NrZWRhc3RpY2l0eSwgaXMgdGhhdCBpdCBjYW4gYmUgbW9kaWZpZWQgdG8gYWxsb3cgZm9yIHVua25vd24gaGV0ZXJvc2tlZGFzdGljaXR5LiAoVGhlIHN0YXRpc3RpYyB3ZSB1c2UgaGVyZSBhc3N1bWVzIEFzc3VtcHRpb24gTUxSLjUsIGhvbW9za2VkYXN0aWNpdHksIGJ1dCB3ZSBjYW4gcmVsYXggdGhhdC4pIFRoZSBTU1IgYXBwcm9hY2ggaW50cmluc2ljYWxseSByZWxpZXMgb24gQXNzdW1wdGlvbiBNTFIuNS4KIAoKIAogV2UgY2FuIHNlZSB0aGUgZGlmZmVyZW50IGludGVyYWN0aW9ucyB2aXN1YWxseSAoYW4gZXhhbXBsZSB3aXRoIHJhbmRvbWx5IGdlbmVyYXRlZCBkYXRhKQogCmBgYHtyfQojIGdlbmVyYXRlIGFydGlmaWNpYWwgZGF0YQpzZXQuc2VlZCgxKQoKWCA8LSBydW5pZigyMDAsMCwgMTUpCkQgPC0gc2FtcGxlKDA6MSwgMjAwLCByZXBsYWNlID0gVCkKWSA8LSA0NTAgKyAgMTUwICogWCArIDUwMCAqIEQgKyA1MCAqIChYICogRCkgKyBybm9ybSgyMDAsIHNkID0gMzAwKQoKIyBlc3RpbWF0ZSB0aGUgbW9kZWxzIGFuZCBwbG90IHRoZSByZWdyZXNzaW9uIGxpbmVzCgojIDEuIChiYXNlbGluZSBtb2RlbCkKcGxvdChYLCBsb2coWSksCiAgICAgcGNoID0gMjAsCiAgICAgY29sID0gInN0ZWVsYmx1ZSIsCiAgICAgbWFpbiA9ICJEaWZmZXJlbnQgSW50ZXJjZXB0cywgU2FtZSBTbG9wZSIpCgptb2QxX2NvZWYgPC0gbG0obG9nKFkpIH4gWCArIEQpJGNvZWZmaWNpZW50cwoKYWJsaW5lKGNvZWYgPSBjKG1vZDFfY29lZlsxXSwgbW9kMV9jb2VmWzJdKSwgCiAgICAgICBjb2wgPSAicmVkIiwKICAgICAgIGx3ZCA9IDEuNSkKCmFibGluZShjb2VmID0gYyhtb2QxX2NvZWZbMV0gKyBtb2QxX2NvZWZbM10sIG1vZDFfY29lZlsyXSksIAogICAgICAgY29sID0gImdyZWVuIiwKICAgICAgIGx3ZCA9IDEuNSkKICAgICAgIAojIDIuIChiYXNlbGluZSBtb2RlbCArIGludGVyYWN0aW9uIHRlcm0pCnBsb3QoWCwgbG9nKFkpLAogICAgIHBjaCA9IDIwLAogICAgIGNvbCA9ICJzdGVlbGJsdWUiLAogICAgIG1haW4gPSAiRGlmZmVyZW50IEludGVyY2VwdHMsIERpZmZlcmVudCBTbG9wZXMiKQoKbW9kMl9jb2VmIDwtIGxtKGxvZyhZKSB+IFggKyBEICsgWDpEKSRjb2VmZmljaWVudHMKCmFibGluZShjb2VmID0gYyhtb2QyX2NvZWZbMV0sIG1vZDJfY29lZlsyXSksIAogICAgICAgY29sID0gInJlZCIsCiAgICAgICBsd2QgPSAxLjUpCgphYmxpbmUoY29lZiA9IGMobW9kMl9jb2VmWzFdICsgbW9kMl9jb2VmWzNdLCBtb2QyX2NvZWZbMl0gKyBtb2QyX2NvZWZbNF0pLCAKICAgICAgIGNvbCA9ICJncmVlbiIsCiAgICAgICBsd2QgPSAxLjUpCgojIDMuIChvbWlzc2lvbiBvZiBEIGFzIHJlZ3Jlc3NvciArIGludGVyYWN0aW9uIHRlcm0pCnBsb3QoWCwgbG9nKFkpLAogICAgIHBjaCA9IDIwLAogICAgIGNvbCA9ICJzdGVlbGJsdWUiLAogICAgIG1haW4gPSAiU2FtZSBJbnRlcmNlcHQsIERpZmZlcmVudCBTbG9wZXMiKQoKbW9kM19jb2VmIDwtIGxtKGxvZyhZKSB+IFggKyBYOkQpJGNvZWZmaWNpZW50cwoKYWJsaW5lKGNvZWYgPSBjKG1vZDNfY29lZlsxXSwgbW9kM19jb2VmWzJdKSwgCiAgICAgICBjb2wgPSAicmVkIiwKICAgICAgIGx3ZCA9IDEuNSkKCmFibGluZShjb2VmID0gYyhtb2QzX2NvZWZbMV0sIG1vZDNfY29lZlsyXSArIG1vZDNfY29lZlszXSksIAogICAgICAgY29sID0gImdyZWVuIiwKICAgICAgIGx3ZCA9IDEuNSkKYGBgCiAKIEEgZmluYWwgd2FybmluZzogaXQgaXMgaGFyZCB0byBqdXN0aWZ5IG9taXR0aW5nIHRoZSBsZXZlbCBvZiBhIHZhcmlhYmxlIGJ1dCBpbmNsdWRpbmcgYW4gaW50ZXJhY3Rpb24gdGhhdCBpbnZvbHZlcyB0aGF0IHZhcmlhYmxlLiBTdXBwb3NlIHdlIGRyb3AgY29sbCBidXQgaW5jbHVkZSBmZW1hbGUgwrcgY29sbC4KIAogVGhlIG1vZGVsIGltcG9zZXMgYSB6ZXJvIHJldHVybiB0byBjb2xsZWdlIGZvciBtZW4g4oCTIHdoaWNoIHdlIGNhbm5vdCBqdXN0aWZ5IOKAkyBhbmQgdGhlIGNvZWZmaWNpZW50IG9uIGZlbWNvbGwgaXMgbm93IGEgZGlyZWN0IGVzdGltYXRlIG9mIHRoZSByZXR1cm4gdG8gY29sbGVnZSBmb3Igd29tZW4sIHJhdGhlciB0aGFuIGJlaW5nIHRoZSBkaWZmZXJlbmNlIGluIHRoZSByZXR1cm5zIGJldHdlZW4gd29tZW4gYW5kIG1lbgoKIyMgTGluZWFyIFByb2JhYmlsaXR5IE1vZGVsCgpXaGF0IGlmIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgaXMgYSBkdW1teSB2YXJpYWJsZT8KCkhvdyBkbyB3ZSBpbnRlcnByZXQgdGhlIHBvcHVsYXRpb24gbW9kZWw6CgpcYmVnaW57ZXF1YXRpb259eSA9XGJldGEgX3swfSArXGJldGEgX3sxfSB4X3sxfSArXGJldGEgX3syfSB4X3syfSArXGxkb3RzICArXGJldGEgX3trfSB4X3trfSArdQpcZW5ke2VxdWF0aW9ufXdoZW4gJHkkIGlzIGJpbmFyeT8gJHkkIGNhbiBvbmx5IGNoYW5nZSBmcm9tIDAgdG8gMSBvciAxIHRvIHplcm8uIFN1cHBvc2UgJFxiZXRhIF97MX0gPS4wMzUkIGFuZCAkeF97MX0gPWVkdWMkLiBXaGF0IGRvZXMgaXQgbWVhbiBmb3IgYSBvbmUgeWVhciBpbmNyZWFzZWQgaW4gJGVkdWMkIHRvIGluY3JlYXNlICR5JCBieSAkLjAzNVx0ZXh0ez99JCAKClNhbWUgcHJvYmxlbSBhcmlzZXMgZm9yIG90aGVyIGRpc2NyZXRlIHZhcmlhYmxlcywgc3VjaCBhcyAkeSA9bnVtYmVyJCAkb2YkICRhcnJlc3RzJCBvciAkeSA9bnVtYmVyJCAkb2YkICRjaGlsZHJlbiQuIENhbm5vdCBoYXZlIGEgZnJhY3Rpb24gbW9yZSBvZiBhIGNoaWxkLgoKVGhlIGtleSByZWxhdGlvbnNoaXAgd2hlbiAkeSQgaXMgYmluYXJ5OiAKClxiZWdpbntlcXVhdGlvbip9RSAoeVx2ZXJ0IFxtYXRoYmZ7eH0pID1QICh5ID0xXHZlcnQgXG1hdGhiZnt4fSkKXGVuZHtlcXVhdGlvbip9XHBhclxwYWdlYnJlYWtccmVsYXggCgoKV2UgY2FsbCAkUCAoeSA9MVx2ZXJ0IFxtYXRoYmZ7eH0pJCB0aGUgXHRleHRiZntyZXNwb25zZSBwcm9iYWJpbGl0eX0uIFRodXMsIHdlbiB3ZSBhcHBseSB0aGUgbGluZWFyIG1vZGVsIHRvIGJpbmFyeSAkeSQgd2UgYXJlIHJlYWxseSBzYXlpbmcgCgpcYmVnaW57ZXF1YXRpb24qfVAgKHkgPTFcdmVydCBcbWF0aGJme3h9KSA9XGJldGEgX3swfSArXGJldGEgX3sxfSB4X3sxfSArXGJldGEgX3syfSB4X3syfSArXGxkb3RzICArXGJldGEgX3trfSB4X3trfQpcZW5ke2VxdWF0aW9uKn1hbmQgd2UgY2FsbCB0aGUgbW9kZWwgdGhlIFx0ZXh0YmZ7bGluZWFyIHByb2JhYmlsaXR5IG1vZGVsIChMUE0pfS4gCgpUaGUgaW1wb3J0YW50IHBvaW50IGlzIHRoYXQgYWxsIHBhcnRpYWwgZWZmZWN0cyBhcmUgZWZmZWN0cyBvbiB0aGUgcHJvYmFiaWxpdHkgdGhhdCAkeSA9MSQgKHNvbWV0aW1lcyBjYWxsZWQgYSBgYHN1Y2Nlc3MnJykuIFNpbmNlICRQICh5ID0wXHZlcnQgXG1hdGhiZnt4fSkgPTEgLVAgKHkgPTFcdmVydCBcbWF0aGJme3h9KSQgaXQgaXMgdGhlIG9ubHkgcHJvYmFiaWxpdHkgd2UgbmVlZC4gCgpcYmVnaW57ZXF1YXRpb24qfSBcRGVsdGEgUCAoeSA9MVx2ZXJ0IFxtYXRoYmZ7eH0pID1cYmV0YSBfe2p9ICBcRGVsdGEgeF97an1cdGV4dHtob2xkaW5nIG90aGVyIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBmaXhlZH0KXGVuZHtlcXVhdGlvbip9XHBhclxwYWdlYnJlYWtccmVsYXggCgpUaGUgc2FtcGxlIGFuYWxvZyBob2xkcyBhcyB3ZWxsLiBXaGVuIHdlIGhhdmUgdGhlIE9MUyByZWdyZXNzaW9uIGxpbmUgCgpcYmVnaW57ZXF1YXRpb24qfVxoYXR7eX0gPVxoYXR7XGJldGEgfV97MH0gK1xoYXR7XGJldGEgfV97MX0geF97MX0gK1xoYXR7XGJldGEgfV97Mn0geF97Mn0gK1xsZG90cyAgK1xoYXR7XGJldGEgfV97a30geF97a31cdGV4dHssfQpcZW5ke2VxdWF0aW9uKn0KKiokXGhhdHt5fSQgaXMgbm93IHRoZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdHkuICoqCgpUaGUgaW50ZXJjZXB0IGlzIHRoZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdHkgd2hlbiBlYWNoICR4X3tqfSQgaXMgc2V0IHRvIHplcm8gKHdoaWNoLCBhcyB3aXRoIG90aGVyIHJlZ3Jlc3Npb24gYXBwbGljYXRpb25zLCBtYXkgbm90IG1ha2Ugc2Vuc2UpLgoKJFxoYXR7XGJldGEgfV97an0kIG1lYXN1cmVzIHRoZSBjaGFuZ2UgaW4gdGhlICoqZXN0aW1hdGVkIHByb2JhYmlsaXR5Kiogb2YgYSBgYHN1Y2Nlc3MnJ1wgd2hlbiAkIFxEZWx0YSB4X3tqfSA9MSQsIG90aGVyIGZhY3RvcnMgaGVsZCBmaXhlZC4gCgpKdXN0IGxpa2UgaW4gYW55IHJlZ3Jlc3Npb24gYXBwbGljYXRpb24sIHdlIGNhbiBoYXZlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBpbiBsb2dzLCBxdWFkcmF0aWNzLCBhbmQgaW50ZXJhY3Rpb25zIGFzIHdlbGwgYXMgYmluYXJ5IHJlZ3Jlc3NvcnMuCgpMZXQncyB0YWtlIHRoZSBmb2xsb3dpbmcgZXhhbXBsZToKVGhlIHZhcmlhYmxlIGlubGYgaXMgb25lIGlmIGEgd29tYW4gd29ya2VkIGZvciBhIHdhZ2UgZHVyaW5nIGEgY2VydGFpbiB5ZWFyLCBhbmQgemVybyBpZiBub3QuIFdlIGVzdGltYXRlIGEgbGluZWFyIHByb2JhYmlsaXR5IG1vZGVsIHRvIHNlZSB0aGUgZWZmZWN0cyBvZiB2YXJpYWJsZXMgb24gdGhlIHByb2JhYmlsaXR5IG9mIGJlaW5nIGluIHRoZSBsYWJvciBmb3JjZS4KYGBge3J9CmxpYnJhcnkod29vbGRyaWRnZSkKZGF0YSgibXJveiIpCgpzdW1tYXJ5KGxtKGlubGZ+bndpZmVpbmMrZWR1YytleHBlcitleHBlcnNxK2FnZStraWRzbHQ2K2tpZHNnZTYsIGRhdGEgPSBtcm96KSkKYGBgClRoZXNlIGFyZSB0aGUgdXN1YWwgT0xTIHQgc3RhdGlzdGljcywgZXZlbiB0aG91Z2ggd2Ugd2lsbCBzaG93IHRoZXkgYXJlIG5vdCBxdWl0ZSB2YWxpZC4KClRoZSBpbnRlcmNlcHQgaXMgbm90IG9mIGludGVyZXN0IGhlcmUuIFRoZSBjb2VmZmljaWVudCBvbiBud2lmZWluYyAob3RoZXIgc291cmNlcyBvZiBpbmNvbWUpIHNob3dzIGEgbW9kZXN0IGVmZmVjdDogaWYgaXQgaW5jcmVhc2VzIGJ5IDIwICgkMjAsIDAwMCwgYWJvdXQgb25lIHN0YW5kYXJkIGRldmlhdGlvbiksIHRoZSBwcm9iYWJpbGl0eSBvZiBiZWluZyBpbiB0aGUgbGFib3IgZm9yY2UgZmFsbHMgYnkgLjA2OCwgb3IgNi44IHBlcmNlbnRhZ2UgcG9pbnRzLiBUaGUgdCBzdGF0aXN0aWMgc2hvd3MgaXQgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBhdCB0aGUgMiUgbGV2ZWwuCgpFYWNoIHllYXIgb2YgZWR1Y2F0aW9uIGluY3JlYXNlcyB0aGUgcHJvYmFiaWxpdHkgYnkgYW4gZXN0aW1hdGVkIC4wMzgsIG9yIDMuOCBwZXJjZW50YWdlIHBvaW50cy4KClVzaW5nIGEgbGluZWFyIG1vZGVsIGZvciBhIGJpbmFyeSBvdXRjb21lIGlzIGNvbnZlbmllbnQgYmVjYXVzZSBlc3RpbWF0aW9uIGlzIGVhc3kgYW5kIHNvIGlzIGludGVycHJldGF0aW9uLgoKUGFzdCB3b3JrZm9yY2UgZXhwZXJpZW5jZSBoYXMgYSBwb3NpdGl2ZSBidXQgZGltaW5pc2hpbmcgZWZmZWN0LiBUaGUgZWZmZWN0IG9mIHRoZSBmaXJzdCB5ZWFyIGlzIGFib3V0IC4wMzksIGFuZCB0aGlzIGRpbWluaXNoZXMgdG8gemVybyBhdCBleHBlciA9IC4wMzkvKDIgwrcgLjAwMDYpID0gMzIuNS4gKE9ubHkgMTMgd29tZW4gaGF2ZSBleHBlcmllbmNlID4gMzIuKQoKSGF2aW5nIHlvdW5nIGNoaWxkcmVuIGhhcyBhIHZlcnkgbGFyZ2UgbmVnYXRpdmUgZWZmZWN0OiBiZWluZyBpbiB0aGUgbGFib3IgZm9yY2UgZmFsbHMgYnkgLjI2MiBmb3IgZWFjaCB5b3VuZyBjaGlsZC4gQWxtb3N0IGFsbCBvZiB0aGUgYWN0aW9uIGlzIGJldHdlZW4gMCBhbmQgMSwgd2l0aCBhIGxpdHRsZSBmcm9tIDEgdG8gMi4KCkl0IGlzIHVud2lzZSB0byBleHRyYXBvbGF0ZSB0byBleHRyZW1lIHZhbHVlcyB3aGVuIHVzaW5nIGFueSBsaW5lYXIgbW9kZWwsIGluY2x1ZGluZyB0aGlzIG9uZSAodmFsdWVzIGNhbiBnbyBhYm92ZSAxCgpCdXQgdGhlIExQTSBkb2VzIGhhdmUgc29tZSBzaG9ydGNvbWluZ3M6CgoxLiBUaGUgZml0dGVkIHZhbHVlcyBmcm9tIGFuIE9MUyByZWdyZXNzaW9uIGFyZSBuZXZlciBndWFyYW50ZWVkIHRvIGJlIGJldHdlZW4gemVybyBhbmQgb25lLCB5ZXQgdGhlc2UgZml0dGVkIHZhbHVlcyBhcmUgZXN0aW1hdGVkIHByb2JhYmlsaXRpZXMuCgotIFRoaXMgY2FuIGJlIHNsaWdodGx5IGVtYmFyYXNzaW5nIGJ1dCBpcyByYXJlbHkgYSBiaWcgZGVhbC4gV2UgdXN1YWxseSB1c2UgdGhlIExQTSB0byBlc3RpbWF0ZSBwYXJ0aWFsIGVmZmVjdHMsIG5vdCB0byBtYWtlIHByZWRpY3Rpb25zLiBGdXJ0aGVyLCBhIG5hdHVyYWwgcHJlZGljdG9yIChzZWUgYmVsb3cpIGlzIG5vdCBzZW5zaXRpdmUgdG8gbmVnYXRpdmUgZml0dGVkIHZhbHVlcyBvciBmaXR0ZWQgdmFsdWVzIGFib3ZlIG9uZS4KCjIuIFRoZSBlc3RpbWF0ZWQgcGFydGlhbCBlZmZlY3RzIGFyZSBjb25zdGFudCB0aHJvdWdob3V0IHRoZSByYW5nZSBvZiB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzLCBwb3NzaWJseSBsZWFkaW5nIHRvIHNpbGx5IGVzdGltYXRlZCBlZmZlY3RzIGZvciBsYXJnZSBjaGFuZ2VzLiAoVGhpcyBpcyByZWxhdGVkIHRvIHByZWRpY3RlZCBwcm9iYWJpbGl0aWVzIHBvc3NpYmx5IGJlaW5nIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiBvbmUuKQoKLSBUaGlzIGlzIG1vcmUgb2YgYSBwcm9ibGVtIGJlY2F1c2Ugd2Uga25vdyB0aGF0LCBzYXksIGEgdmFyaWFibGUgd2l0aCBhIHBvc2l0aXZlIGVmZmVjdCBvbiBQKHkgPSAxfHgpIG11c3QgZXZlbnR1YWxseSBoYXZlIGEgZGltaW5pc2hpbmcgZWZmZWN0LiBCdXQgdGhlIGxpbmVhciBtb2RlbCBpbXBsaWVzIGEgY29uc3RhbnQgZWZmZWN0ICh3aGVuIHRoZSB2YXJpYWJsZSBhcHBlYXJzIGJ5IGl0c2VsZikuCgpGb3IgZXhhbXBsZSwgdGFrZSBhIHdvbWFuIHdobyBoYXMgbm8gb3RoZXIgc291cmNlIG9mIGluY29tZSwgMjUgeWVhcnMgb2YgcHJpb3Igd29yayBleHBlcmllbmNlLCBubyBjaGlsZHJlbiwgd2hvIGlzIDQ4IHllYXJzIG9sZC4KQXMgYSBmdW5jdGlvbiBvZiAkZSBkIHUgYyQgdGhlIGVxdWF0aW9uIGxvb2tzIGxpa2UgCgpcYmVnaW57ZXF1YXRpb24qfVx3aWRlaGF0e2kgbiBsIGZ9ID0uNDE3ICsuMDM4XHRleHR7fWUgZCB1IGMKXGVuZHtlcXVhdGlvbip9CgpBdCAkZSBkIHUgYyA9MTIkLCB0aGUgcHJlZGljdGVkIHByb2JhYmlsaXR5IGlzICQuODczJCwgYXQgJGUgZCB1IGMgPTE0JCBpdCBpcyAkLjk0OSQsIGFuZCBhdCAkZSBkIHUgYyA9MTYkLCAkXHdpZGVoYXR7aSBuIGwgZn0gPTEuMDI1JC4gRm9yIHRoZSBlc3RpbWF0ZWQgbW9kZWwgdG8gdHJ1bHkgcmVwcmVzZW50IGEgcHJvYmFiaWxpdHksIHRoZSBlZmZlY3Qgb2YgZWR1Y2F0aW9uIHNob3VsZCBiZSBkaW1pbmlzaGluZyAtLSB0aGF0IGlzLCB0aGUKbmV4dCB5ZWFyIG9mIGVkdWNhdGlvbiBzaG91bGQgaW5jcmVhc2UgdGhlIHByb2JhYmlsaXR5IGJ5IGxlc3MgdGhhbiB0aGUgcHJldmlvdXMgeWVhciBzbyB0aGF0IHRoZSBlc3RpbWF0ZWQgcHJvYmFiaWxpdHkgbmV2ZXIgZ29lcyBhYm92ZSBvbmUuCgpVc2luZyBsb2dhcml0aG1zIGRvZXMgbm90IGJvdW5kIHRoZSBlZmZlY3QsIGFuZCB1c2luZyBxdWFkcmF0aWNzIG9mdGVuIGRvZXMgbm90IGhlbHAuIChJbiB0aGlzIGV4YW1wbGUsIGEgcXVhZHJhdGljIGluICRlIGQgdSBjJCBnaXZlcyBhbiBlc3RpbWF0ZWQgXHRleHRpdHtpbmNyZWFzaW5nfSBlZmZlY3QsIG5vdCBhIGRpbWluaXNoaW5nIGVmZmVjdC4pIHdpdGggdGhpcyBwcm9ibGVtLiAKCkJ1dCB0aGUgTFBNIGRvZXMgYSBnb29kIGpvYiBvZiBhcHByb3hpbWF0aW5nIHBhcnRpYWwgZWZmZWN0cyBpZiB3ZSBkbyBub3QgbG9vayBhdCBleHRyZW1lIHZhbHVlcyBvZiB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzLgoKXHRleHRiZnszLn0gQmVjYXVzZSAkeSQgaXMgYmluYXJ5IC0tIGFuZCB0aGlzIHJlYWxseSBoYXMgbm90aGluZyB0byBkbyB3aXRoIHRoZSBMUE1cIHBlciBzZSAtLSB0aGUgTFBNIG11c3QKZXhoaWJpdCBoZXRlcm9za2VkYXN0aWNpdHkgZXhjZXB0IGluIHRoZSBvbmUgY2FzZSB3aGVyZSBubyAkeF97an0kIGFmZmVjdHMgJFAgKHkgPTFcdmVydCBcbWF0aGJme3h9KSQuIFRoaXMgZm9sbG93cyBiZWNhdXNlIGZvciBhIGJpbmFyeSB2YXJpYWJsZSwgCgpcYmVnaW57ZXF1YXRpb24qfVYgYSByICh5XHZlcnQgXG1hdGhiZnt4fSkgPXAgKFxtYXRoYmZ7eH0pWzEgLXAoXG1hdGhiZnt4fSldClxlbmR7ZXF1YXRpb24qfXdoZXJlICRwIChcbWF0aGJme3h9KSA9XGJldGEgX3swfSArXGJldGEgX3sxfSB4X3sxfSArXGJldGEgX3syfSB4X3syfSArXGxkb3RzICArXGJldGEgX3trfSB4X3trfSQgaXMgdGhlIGxpbmVhciByZXNwb25zZSBwcm9iYWJpbGl0eS4gCgpUaGlzIGlzIGEgY2FzZSB3aGVyZSB3ZSBcdGV4dGl0e2tub3d9IE1MUi41IG11c3QgZmFpbCwgYW5kIHdlIGtub3cgaG93LiBTbywgY3VycmVudGx5LCB3ZSB0cmVhdCB0aGUgdXN1YWwgJHQkIGFuZCAkRiQgdGVzdHMgd2l0aCBzdXNwaWNpb24sIGFuZCB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbHMuIChUdXJucyBvdXQgdGhleSBhcmUgb2Z0ZW4gcHJldHR5IHJlbGlhYmxlIGluIExQTXMuKQoKU29tZSB0d2VldHMgZnJvbSB0aGUgYXV0aG9yIGFib3V0IExQTSAoQVBFID0gQXZlcmFnZSBQYXJ0aWFsIEVmZmVjdHMpOgohW2xwbV0obHBtX3dvb2xkcmlkZ2UucG5nKQoKIVtscG0yXShscG0yLnBuZykKCkFub3RoZXIgdGhpbmcgdG8gbm90ZSBpcyB0aGF0IG91ciB1c3VhbCAkUl4yJCBkb2Vzbid0IG1lYXN1cmUgZml0IGFzIHdlbGwuIApJbnN0ZWFkLCBpdCdzIGVhc2llciB0byB0aGluayBvZiBwcmVkaWN0aW9uIGluIHRlcm1zIG9mICJzdWNjZXNzIiBhbmQgImZhaWx1cmVzIi4gSXMgdGhlIG1vZGVsIGJldHRlciBhdCBwcmVkaWN0aW5nIHN1Y2Nlc3NlcywgZmFpbHVyZXMsIG9yIGlzIG92ZXJhbGwsIGRvaW5nIGEgZ29vZCBqb2IgcHJlZGljdGluZyBib3RoPwoKVGhlICpmcmFjdGlvbiBjb3JyZWN0bHkgcHJlZGljdGVkKiBpcyBvbmUgd2F5IHRvIHRoaW5rIGFib3V0IGZpdCBpbiBMUE06CiQkXGJhcnt5fSBcdGltZXMgXHRleHR7UHJ9KFxoYXR7WX09MXxZPTEpICsgKDEtXGJhcnt5fSkgXHRpbWVzIFx0ZXh0e1ByfShcaGF0e1l9PTB8WT0wKSQkCndoZXJlICRcYmFye3l9PSBOXnstMX1cc3VtX2leTiBZX2kkLiBXaGF0IGlzICQoMS1cYmFye3l9KSQ/CgpXZSBuZWVkIGEgY2xhc3NpZmljYXRpb24gcnVsZSwgdXN1YWxseSAoYnV0IG5vdCBuZWNlc3NhcmlseSkKCiQgXHRpbGRle3l9X2kgPSAxIH5+XHRleHR7aWZ9fn4gXGhhdHtwfV9pIFxnZXEgMC41ICQgYW5kICRcdGlsZGV7eX1faSA9IDAgfn5cdGV4dHtpZn1+fiBcaGF0e3B9X2kgPCAwLjUkIAoKVGhpcyBjbGFzc2lmaWNhdGlvbiBydWxlIGlzIHVwIHRvIHlvdSBhcyB0aGUgcmVzZWFyY2hlciAtIHdoYXQncyB0aGUgY3V0b2ZmIHJ1bGUgdGhhdCB0aGUgcHJvYmFiaWxpdHkgb2YgWCBiZSBjb3VudGVkIGFzIGEgInN1Y2Nlc3MiLgoKVGhlbiwgd2UgY2FuIGRvIGFsbCBzb3J0cyBvZiBjbGFzc2lmaWNhdGlvbnM6CgotIGZyYWN0aW9uIG9mIGNvcnJlY3RseSBwcmVkaWN0ZWQgc3VjY2Vzc2VzOiAkXHN1bV9pICAxKFx0aWxkZXt5fV9pID0gMSBcd2VkZ2UgWV9pPTEpLyBcc3VtX2kgWV9pJAotIGZyYWN0aW9uIG9mIGNvcnJlY3RseSBwcmVkaWN0ZWQgZmFpbHVyZXM6ICRcc3VtX2kgIDEoXHRpbGRle3l9X2kgPSAwIFx3ZWRnZSBZX2k9MCkvXHN1bV9pIDEoe1l9X2k9MCkkCi0gZnJhY3Rpb24gY29ycmVjdGx5IHByZWRpY3RlZDogJFxzdW1faSAgMShcdGlsZGV7eX1faSA9IFlfaSkgLyBOJC4KCgojIyBSZXNpZHVhbCBBbmFseXNpcwpTb21ldGltZXMgd2Ugd2FudCB0byBrbm93IGhvdyBwYXJ0aWN1bGFyIHVuaXRzIGFjdHVhbGx5IGZhaXIgY29tcGFyZWQgd2l0aCB0aGVpciBwcmVkaWN0ZWQgb3V0Y29tZSBiYXNlZCBvbiB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIHdlIG9ic2VydmUuCgpDb25zaWRlciBwcmVkaWN0aW5nIHNjaG9vbCBwZXJmb3JtYW5jZS4gR2l2ZW4gZGVtb2dyYXBoaWMgaW5mb3JtYXRpb24gb24gdGhlIHN0dWRlbnRzIGFuZCByZXNvdXJjZXMgdXNlZCwgaXMgYSBzY2hvb2wgZG9pbmcgYmV0dGVyIG9yIHdvcnNlIHRoYW4gcHJlZGljdGVkPyAKCkl0IGlzIGtub3duIHRoYXQgc3R1ZGVudHMgZnJvbSBkaXNhZHZhbnRhZ2UgYmFja2dyb3VuZHMgZG8gd29yc2UsIGFuZCBzb21lIGV2aWRlbmNlIHNjaG9vbCBpbnB1dHMgYWxzbyBhZmZlY3Qgb3V0Y29tZXMuCgpTbyBkbyBub3QganVzdCBsb29rIGF0IHJhdyBzY29yZXMsIGJ1dCBhZGp1c3QgdGhlbSBmb3Igb2JzZXJ2YWJsZSBmZWF0dXJlcy4gVGhlIHJlc2lkdWFsIGNhbiBiZSB2aWV3ZWQgYXMgYW4gZXN0aW1hdGUgb2YgdGhlIOKAnHZhbHVlIGFkZGVkLuKAnQoKXGJlZ2lue2dhdGhlcip9XGhhdHt1fV97aX0gPXlfe2l9IC1caGF0e3l9X3tpfSBcXApcaGF0e3V9X3tpfSA+MCBcTG9uZ3JpZ2h0YXJyb3cgeV97aX0gPlxoYXR7eX1fe2l9IFxcClxoYXR7dX1fe2l9IDwwIFxMb25ncmlnaHRhcnJvdyB5X3tpfSA8XGhhdHt5fV97aX1cZW5ke2dhdGhlcip9CgpDYXZlYXRzOiAKCjEuICBUaGUgcmVzaWR1YWxzIGhhdmUgdG8gYXZlcmFnZSB0byB6ZXJvLCBzbyB0aGVyZSB3aWxsIGJlIHNvbWUgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHJlc2lkdWFscyBubyBtYXR0ZXIgd2hhdC4gCgoyLiBUaGUgcmVzaWR1YWwgZGVwZW5kcyBvbiB0aGUgZXN0aW1hdGVzLCAkXGhhdHvOsl9qfSQuCgozLiBFdmVuIGlmIHdlIGtub3cgdGhlICTOsl9qLCB1X2kkIGlzIGp1c3QgYSBzaW5nbGUgZHJhdy4KCjQuIFdlIG1heSBiZSBtaXNzaW5nIGltcG9ydGFudCBwcmVkaWN0b3JzIG9mIHkgdGhhdCBhcmUgdGhlbiBpbiB0aGUgZXJyb3IgdGVybS4KCmBgYHtyfQpkYXRhKG1lYXAwMF8wMSkKc2Nob29sIDwtIGxtKG1hdGg0IH4gbHVuY2ggK2xlbnJvbGwrIGxleHBwcCwgZGF0YT1tZWFwMDBfMDEpCnN1bW1hcnkoc2Nob29sKQpwcmVkaWN0X3NjaG9vbDwtIHRpYmJsZShwcmVkaWN0KHNjaG9vbCkpCmBgYAoKClRoZSBwcmVkaWN0ZWQgdmFsdWVzIHZhcnkgbXVjaCBsZXNzIHRoYW4gdGhlIGFjdHVhbCBvdXRjb21lcyAodGhlIGZhaXJseSBsb3cgUi1zcXVhcmVkLCAuMzcyLCBpbXBsaWVzIHRoaXMpLgoKQ29uc2lkZXIgc2Nob29scyAzIGFuZCA0LiBUaGVpciBwcmVkaWN0ZWQgb3V0Y29tZXMgKGJhc2VkIG9uIGx1bmNoLCBsZW5yb2xsLCBsZXhwcHApIGFyZSBjbG9zZSwgYWJvdXQgODAuOTUgYW5kIDc3LjE2LCByZXNwZWN0aXZlbHkuIEJ1dCB0aGUgYWN0dWFsIG91dGNvbWUgZm9yIHNjaG9vbCA0LCA4NS4yLCBpcyAxMCBwb2ludHMgaGlnaGVyIHRoYW4gc2Nob29sIDMsIDc3LjMuCgpXaXRoIG9ubHkgYSBmZXcgZXhwbGFuYXRvcnkgdmFyaWFibGVzLCByZXNpZHVhbCBhbmFseXNpcyBjYW4gYmUgbWlzbGVhZGluZy4gV2UgbWF5IGJlIG1pc3NpbmcgaW1wb3J0YW50IGZhY3RvcnMgdGhhdCwgaWYgY29udHJvbGxlZCBmb3IsIGNvdWxkIGRyYW1hdGljYWxseSBjaGFuZ2UgdGhlIHJhbmtpbmdzLgoKV2UgY2FuIGFsc28gb2JzZXJ2ZSBvdXIgcmVzaWR1YWxzIGFuZCBkbyBhIHZpc3VhbCBpbnNwZWN0aW9uIG9mIHJlc2lkdWFscyAtIHJlbWVtYmVyaW5nIHRoZSBjYXZlYXRzLiAKCkluIHRoZSBmaXJzdCBncmFwaCwgd2UgY2FuIHNlZSB0aGUgcmVzaWR1YWxzIHZlcnN1cyB0aGUgZml0dGVkLiBUaGlzIGdyYXBoLCBhcyB3ZSB0YWxrZWQgYWJvdXQgYmVmb3JlLCBzaG93cyB0aGUgcHJlc2VuY2Ugb2YgaGV0ZXJvc2tlZGFzdGljaXR5LiAoUmVtZW1iZXIgdGhhdCB0aGUgYXZlcmFnZSBvZiBvdXIgcmVzaWR1YWxzIHNob3VsZCBiZSAwLCBzbyB0aGF0IHJlZCBsaW5lIHNob3dzIGp1c3QgdGhhdCAtIGl0J3MgYXBwcm94aW1hdGVseSAwKS4gV2Ugc3VzcGVjdCBoZXRlcm9za2VkYXN0aWNpdHkgYmVjYXVzZSBvZiB0aGUgImZ1bm5lbCIgc2hhcGUuIFRoZSBzY2FsZS1sb2NhdGlvbiBncmFwaCBzaW1pbGFybHkgc2hvd3MgdGhpcyBwYXR0ZXJuICh3ZSdkIGJlIHNob2NrZWQgb3RoZXJ3aXNlLCBhZnRlciBhbGwgdGhlIFNFUiBpcyB0aGUgYXZlcmFnZSBtaXN0YWtlIHdlIG1ha2UgaW4gb3VyIHJlZ3Jlc3Npb24gYW5kIGlzIGEgbWVhc3VyZSBvZiBmaXQpCgpUaGlzIGlzIHVzZWZ1bCB0byBsb29rIGF0IHRvIGluc3BlY3QgaXNzdWVzIHdpdGggdGltZS1zZXJpZXMuCgoKYGBge3J9CgpwbG90KHNjaG9vbCkKCmBgYAoKCgpXZSBjYW4gYWxzbyBhbmFseXplIHRoZSByZXNpZHVhbCBkaXN0cmlidXRpb24uIEl0IHNob3VsZCBiZSBjbG9zZSB0byBhIG5vcm1hbCBkaXN0cmlidXRpb24gZ2l2ZW4gb3VyIGFzc3VtcHRpb25zLiAKYGBge3J9CnU8LW1lYXAwMF8wMSRtYXRoNCAtIHByZWRpY3Rfc2Nob29sJCdwcmVkaWN0KHNjaG9vbCknCgpwcmVkaWN0X3NjaG9vbApkIDwtIGRlbnNpdHkodSkKcGxvdChkKQpwb2x5Z29uKGQsIGNvbD0icmVkIiwgYm9yZGVyPSJibHVlIikKCmBgYAoKCgo=